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?
Post
Replies
Boosts
Views
Activity
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()
}
}
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?
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
}
}
I am trying to add a UITableView element to a XIB which I want to present as a sheet from the bottom but I only get the option of static cells.
Isn't it possible to have dynamic tables within a XIB or am I missing something?
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
}
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