Post

Replies

Boosts

Views

Activity

UIAlertAction handler/closure does not execute
I have an UIViewController extension which I am using to display alerts in any view controller. It worked fine until this weird use case happened: extension UIViewController { func showModal(title: String, msg: String, handler: ((UIAlertAction) -> Void)? = nil) { let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: handler)) DispatchQueue.main.async { self.present(alert, animated: true, completion: nil) } } } Inside a view controller I tap a button which triggers a network fetch: @IBAction func didTapSave(_ sender: UIButton) { Task { let result = await BalanceManager.shared.fetchAllBalances() switch result { case .success(_): self.showModal(title: "", msg: "account successfully saved") { (_) in //This code always gets executed self.navigationController?.popViewController(animated: true) } case .failure(let failure): self.showModal(title: "", msg: "failure") { (_) in //Code in here is not executed print("Failure closure") } } } I don't understand why on case ".failure" the closure for showModal does not execute. If I set a breakpoint on the line with self.showModal the code gets there but does not execute the closure when I tap "OK" on the popup
2
0
895
Oct ’22
Debugger crashes if breakpoint set in @objc func triggered by Notification
My BalanceManager object is called at app startup and after it fetches some data, it posts a notification. In the @objc implementation of the SplashScreenVC observer I am setting a breakpoint. The debugger crashes with the following log: Message from debugger: The LLDB RPC server has crashed. You may need to manually terminate your process. The crash log is located in ~/Library/Logs/DiagnosticReports and has a prefix 'lldb-rpc-server'. Please file a bug and attach the most recent crash log. I am using this SplashScreenVC that listens for this notification to fetch data, load some user defaults etc. The data fetch runs without problem and I don't have this kind of debugging problem in other views in my program. The debugger crashes only in this particular ViewController which is also my main program entry point Any ideas why this thing happens? override func viewDidLoad() {     super.viewDidLoad()     setupUI() NotificationCenter.default.addObserver(self, selector: #selector(balancesDidUpdate), name: .balancesUpdated, object: BalanceManager.shared)           //Fetch data     Task { await BalanceManager.shared.fetchData() }           }    @objc func balancesDidUpdate(_ notification: Notification) {     print("balancesDidUpdate in SplashScreenVC via notification")      //more code here    }
0
0
799
Sep ’22
How to trigger textFieldDidChangeSelection only for a specific UITextField?
In a view with multiple UITextField elements, textFieldDidChangeSelection will trigger for any editing done in any UITextField. Can we perform some action inside this function only when a certain UITextField is edited? class MyViewController: UIViewController, UITextFieldDelegate { @IBOutlet weak var text1: UITextField! @IBOutlet weak var text2: UITextField! @IBOutlet weak var text2: UITextField! //.......... func textFieldDidChangeSelection(_ textField: UITextField) { print(textField.text) // this code should run only for text1 for example } }
1
0
653
Jun ’22
TableView model updated asynchronously sometimes crashes the app
In my app I am fetching RESTful data asynchronously from mutiple servers and merge the responses into an array when they are available: let respModel = [responses] I use didSet to check whether respModel is set and then trigger myTableView.reloadData() to udpate the table view each time Sporadically, my app crashes during table view refresh and I think it's because two RESTful api calls arrive at exactly the same time, creating a deadlock on the respModel I want to keep the current async functionality in, to get my table view updated whenever a fresh response arrives, but I also want to find a solution to the deadlock problem. What's the best way to handle it?
1
0
519
Jun ’22
Async @objc didPullToRefresh selector crashes app swift 5.5
I have a table to which I've added a refreshControl and when I pull down the table to refresh the data, I reset the array that feeds the table with data and then immediately request new data through an API call. Until now, I have used completion handlers and protocols to get the data into the table view but I want to move the logic to async/await because of the complexity needed by the network calls and the pyramid of nested closures. Populating the view in viewDidLoad works fine but with pullToRefresh selector I get an error: Thread 1: EXC_BAD_ACCESS (code=1, address=0xbcf917df8160) override func viewDidLoad() {     super.viewDidLoad()     setupView()     setupTableView()     setupTableRefreshControl()     Task {       await getBalances() //async network call       myTable.reloadData()     }   }    func setupTableRefreshControl() {     myTable.refreshControl = UIRefreshControl()     myTable.refreshControl?.addTarget(self, action: #selector(didPullToRefresh), for: .valueChanged)   } Code that crashes app:    @objc func didPullToRefresh() async {     balance.reset() // reset array to []     Task {       await getBalances() //async network call       myTable.reloadData()     }   }
1
0
851
Feb ’22
Enable/Disable UISlider when a SegmentControl is selected in Table cell
Hello, I am currently learning and developing my first iOS app and I have created a custom UITableViewCell using a XIB file in which I have integrated a UISlider and a SegmentedControl button. What I want to accomplish is the first time the table loads up, the UISlider is disabled - I accomplish this in awakeFromNib and it also corresponds to the 0 value selection of the SegmentedControl. Then when a user touches "One" or "Two" on the SegmentedControl I want to enable the UISlider. I am using a delegated protocol to send the indexPath of the selected cell to my ViewController: extension ViewController: AccountCellDelegate { func segmentControlSelected(at index: IndexPath, segmentValue: Int, slider: UISlider) { slider.isEnabled = (segmentValue != 0) myTableView.reloadRows(at: [index], with: .none) } The problems with this implementation are that I have to click twice on a SegmentedControl button to see its value selected and the UISlider still does not change its appeareance from "faded out - disabled" to normal - enabled unless I click on it. Do you have any idea if reloadRows(at:with:) is the correct way to refresh the cell so that the UISlider appeareance is correctly displayed?
5
0
1.6k
Dec ’21