One of the specifications of my app is that on tapping a tableView cell, the user will be redirected to the website associated with the cell. Here is the code:
Also using Objective-C, using the suggested [modeAlert.view layoutIfNeeded]
reduced errors to one as above. Final error has been suppressed by changing last addAction from UIAlertActionStyleCancel
to UIAlertActionStyleDefault
as below. Not a great workaround to what appears to be a bug.
[modeAlert addAction:[UIAlertAction
actionWithTitle:NSLocalizedString(@"Cancel", @"")
style:UIAlertActionStyleDefault
handler:nil ]];
I was getting a similar debug warning when trying to present a QLPreviewController modally. I've read on other posts that it's an Xcode bug.
For me the error displayed when I ran my app on the simulator but not on an actual device. Must be an Xcode/Simulator issue. Hope that helps.
I was facing the similar problem (same warning XD).
Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.
My Xcode version is 9.4.1, and everything was perfect until I add resignFirstResponder()
in textFieldShouldReturn(_ textField: UITextField)
.
When I touched UITextField
with text in the UITableViewCell
, It will show the warning.
So I changed the way to trigger UITextField
(Edit version). It never show the warning again.
In conclusion, I still don't know why this happened, but what I can do is avoid the warning, hope It will help someone :D
class TableViewCell: UITableViewCell {
// add this in TableViewCell
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
answerTextField.isEnabled = selected
if selected {
answerTextField.becomeFirstResponder()
} else {
answerTextField.resignFirstResponder()
}
}
}
class ViewController: UIViewController {
private let tableView: UITableView = {
let t = UITableView()
t.separatorStyle = .none
t.backgroundColor = .clear
return t
}()
private let cellId = "Cell"
private let data = [
Model(title: "A", answer: "a"),
Model(title: "B", answer: "b"),
Model(title: "C", answer: nil),
Model(title: "D", answer: nil)
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.register(TableViewCell.self, forCellReuseIdentifier: cellId)
view.addSubview(tableView)
tableView.frame = view.frame
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as? TableViewCell {
cell.contentView.backgroundColor = indexPath.section % 2 == 0 ? .gray : .white
cell.setData(data[indexPath.row])
return cell
}
return UITableViewCell()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
}
class TableViewCell: UITableViewCell {
private let titleLabel = UILabel()
private let answerTextField = UITextField()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupViews()
}
func setupViews() {
setupTitleLabels()
}
func setData(_ data: Model) {
titleLabel.text = data.title
answerTextField.text = data.answer
}
private func setupTitleLabels() {
answerTextField.delegate = self
let sv = UIStackView(arrangedSubviews: [titleLabel, answerTextField])
sv.axis = .vertical
sv.spacing = 0
sv.distribution = .fill
contentView.addSubview(sv)
sv.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
sv.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
sv.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
sv.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
}
}
extension TableViewCell: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
struct Model {
let title: String
var answer: String?
init(title: String, answer: String? = nil) {
self.title = title
self.answer = answer
}
}
I had the same problem and found a simple solution that makes sense.
If it's an iPad ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad
) then do NOT add the UIAlertAction
with style UIAlertActionStyleCancel
to the UIAlertController
.
I made this change and my errors went away. This solution makes sense since you don't need a cancel action for alerts with style UIAlertControllerStyleActionSheet
on an iPad.
To avoid copy/paste from Saliom's answer you can make such subclass and use it instead of UIAlertController
:
class AlertController: UIAlertController {
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.view.layoutIfNeeded()
}
}
I think the last warning came from the Cancel button.
On iOS8 the cancel button is shown only when needed. If you run the app on iPhone it is visible. If you run the app on iPad the cancel button is not shown and the handler for the cancel action (style:UIAlertActionStyleCancel) is called when the user taps outside the popup.
the answer come from: amalicka's answer