UISlider issue in ios 16.3.1 [closed] - ios

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 days ago.
Improve this question
I was implementing multiple sliders in a page in ios 14.2. The UI had a tableview and 4 cells. Each cells had a slider. It was working fine in 14.2. But when I updated my iPhone os to 16.3.1, the sliders are not behaving properly.
When I try to move the first slider, the first and fourth slider is moving at the same time. And when second slider is moved, second and third sliders are getting moved. Have anyone encountered with this issue before.

You might be reloading/updating you tableView when slider changes. Do not reload table view.
Create a Model class for you cell
class MyModel {
var title:String?
var sliderValue:CGFloat
}
Pass the model to cell and update you model directly
class MyCustomCell:UITableViewCell{
var model:MyModel!
func configure(item:MyModel) {
self.model = item
}
#IBAction func sliderChanges(_ sender: UiSlider) {
self.model.sliderValue = sender.value
}
}
And finally pass the change your cell for indexPath method
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCustomCell", for:indexPath) as? MyCustomCell
cell.configure(item:self.items[indexPath.row])
return cell
}

Related

update UITableViewCell from content of another UITableViewCell in same table [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
i have a UITableViewController configured with a static table made up of 5 custom cells (this is meant to be a form).
cell 0 captures a date
cell 1 is a UICollectionView filled with icons representing activities. depending on which activity is selected, one of many custom UITableViewCell are loaded on the fly in cell 2 .
cell 2 can be simple (just a slider), a textfield or more complex (a UITableView)
cell 3 has a textfield to capture a description.
cell 4 is for additional notes
so far everything is working as expected. I select an activity in cell 1, the matching XIB is loaded in cell 2, data is captured, comment added etc and form is saved. Where i am challenged is in the case where based on the the input in cell 2, i would like to update cell 3 automatically. i got it working but i feel it isn't elegant or clean so would appreciate others input. in
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// main table cells pseudo code
switch indexPath.row {
case 0:
<#code#>
case 1:
// dequeue collectionviewcell
case 2:
// dequeue the relevant uitableviewcell based on selected cell in the uicollectionview
switch selectedIndexPath.row {
case 2:
<#code#>
default:
<#code#>
}
case 3:
// handle the description field
default:
<#code#>
}
a specific activity will load "eventFlushMedTableViewCell" which is meant to display a list of meds in a uitableview. based on which meds I select, i would like to take the name of the meds and put them in cell 3.
case 2:
let cell = tableView.dequeueReusableCell(withIdentifier: "eventFlushMedTableViewCell", for: indexPath) as! eventFlushMedTableViewCell
// fill the meds table with the list of Rx meds
cell.medsArray = medListArray.filter { $0.medRx == 1}.map {return $0.medName}
// return the selected values from the table
cell.returnValue = { selectedIndexPaths in
let indexList = selectedIndexPaths.map { $0.row }
self.selectedMedsName = indexList.map {cell.medsArray[$0]}
// force a reload of cell 3
let myIndexPath = IndexPath.init(row: 3, section: 0)
tableView.reloadRows(at: [myIndexPath], with: .none)
}
return cell
and cell 3 in the main table is dequeued and configured
case 3:
let cell = tableView.dequeueReusableCell(withIdentifier: "eventDescriptionCell", for: indexPath) as! eventDescriptionCell
if !selectedMedsName.isEmpty {
cell.eventDescriptionTextField.text = selectedMedsName.joined(separator: ", ")
}
something tells me the closure around (cell.returnValue {...}) in case 2:, even though it is working, isn't the right way of doing this... any advice ?
thanks
I think a good way of approaching this would be to create a custom delegate.
Let's name it ActivityCellDelegate. You can create it like this:
protocol ActivityCellDelegate: class {
func activitySelected(_ activity: Activity)
}
We use 'class' so we can make the delegate 'weak' reference. Otherwise XCode will cause trouble :).
Using an enum to represent different activities is a nice touch. You could also use a String as an identifier or an Int as an id.
enum Activity {
case activity1
case activity2
...
}
Add a delegate property to the TableViewCell:
weak var cellDelegate: ActivityCellDelegate?
Then, when dequeuing a cell, you set it's delegate to self cell.cellDelegate = self, and make the controller that has tableView as a subview conform to the delegate protocol.
extension TableViewController: ActivityCellDelegate {
func activitySelected(_ activity: Activity) {
//...in here you would probably reload the third cell in the table view. You could add an additional property in the ViewController in order to know which activity is currently selected.
}
}
In the end, when user selects a CollectionViewCell to choose an activity in collectionView:didSelectItemAtIndexPath: you should call the delegate method:
delegate?.activitySelected(.activity1)

Control "Program Flow" in Table View

again me with a short question since Swift is confusing me ATM - but I hope I will get used to it soon ;)
Ok so what I was wondering is: When I call a TableView and generate different Cells is there a way to Interrupt after a few and wait for User Input and react to it?
For Example: 2nd Cell is something like "Go to North or West" after that I want a User Input - with Buttons - in whatever direction he likes to go and react to it with following Cells (different Story Parts -> out of other Arrays?).
What is confusing me is that I just load the whole Application in viewDidLoad and i don't know how I can control the "Flow" within this.
I would really appreciate if someone could show me how I can achieve this maybe even with a small description about how I can control the Program Flow within the Method. I really think this knowledge and understanding would lift my understanding for Swift a few Levels higher.
Thanks in advance!
Here is my current Code which is not including any functionality for the named Question since I don't know how to manage this :)
import UIKit
class ViewController: UIViewController {
var storyLines = ["Test Cell 1 and so on first cell of many","second cell Go to North or West","third Cell - Buttons?"]
var actualTables = 1
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.dataSource = self
}
#IBOutlet weak var tableView: UITableView!
}
extension ViewController : UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return storyLines.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TxtLine", for: indexPath)
cell.textLabel?.text = storyLines[indexPath.row]
cell.textLabel?.numberOfLines = 0;
cell.textLabel?.lineBreakMode = .byWordWrapping
return cell
}
}
Cocoa is event driven. You are always just waiting for user input. It's a matter of implementing the methods that Cocoa has configured to tell you about it.
So here, for example, if you want to hear about when the user presses a button, you configure the button with an action-and-target to call a method in your view controller when the user presses it. That way, your method can see which button the user pressed and remake the table view's data model (your storyLines array) and reload the table with the new data.

How do I proceed on populating the UITableView [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I got these item properties and I need to populate the UI by setting the name on each UITableViewCell, each cell has the following properties:
Name
Description
Photo
Old Price
New Price
However, I don't know how I should proceed. Could you guys take a look and give me a hand, please?
Printed Item names:
HTML e CSS
Sistema de Banco de Dados
Programação com Arduino
Segredos do Hacker Ético
Google Android
Android Essencial
Desenvolvimento de Jogos Para Android
iOS: Programe para iPhone e iPad
A Guerra dos tronos
Crepusculo
ViewController:
import UIKit
class TelaCategorias: UIViewController, UITableViewDataSource, UITableViewDelegate {
//Class Instanciated
var item:[CategoriaIDItems]?
override func viewDidLoad() {
super.viewDidLoad()
for item in item!{
print(item.nome)
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (item?.count)!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableIDCategorias", for: indexPath) as! TelaCategoriasCell
cell.textLabel?.text = ?????
return cell
}
}
Append the item names to an array
In cellForRowAt indexPath:
cell.textLabel.text = yourArrayName[indexPath.row]
So you need to read up on setting up a data source for a table view.
Before you tackle YOUR table view, you might want to go through a Swift/iOS tutorial on table views and follow that so you get the gist of it.
Suggestion: Don't use the name "item" (singular) for your array. Use the name "items" plural. An item is a thing. Items is more than one thing.
Now define a struct that has fields for the properties that you want to display in your table view.
Make items be an array of those structs.
Write your tableView(_:cellForRowAt:) method so it fetches an item from the items array and uses that item to set the fields in your table view cell.
If you don't understand any of these steps you will need to do some study and read up on how to do this. Expect it to take a couple of days to sort this out. It's confusing the first time you tackle it, but you need to go through the exercise.

Closure as property for UITableViewCell subclass to update value : Is it a bad idea? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I would like some opinions on a idea I just had :
I have a bunch of UITableViewCell subclass. In my particular case it's just to add a UISwitch and have a property to access it.
Setting the switch's value is straight forward. Updating the Bool associated to this switch not so much.
I thought of adding a closure as a property of my cell so that I can just call it to update my bool in my UITableViewController subclass
Here is some the code I thought of :
class SwitchTableViewCell:UITableViewCell {
#IBOutlet var theSwitch:UISwitch!
var switchValueChangedBlock:((Bool) -> Void)?
override func awakeFromNib() {
theSwitch.addTarget(self, action: "switchValueChanged", forControlEvents: .ValueChanged)
}
deinit {
theSwitch.removeTarget(self, action: nil, forControlEvents: .AllEvents)
}
func setCallback(callback:(Bool) -> Void) {
switchValueChangedBlock = callback
}
func switchValueChanged() {
switchValueChangedBlock?(theSwitch.on)
}
}
class myTableViewController:UITableViewController {
var alarmEnabled:Bool = true
...
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell?
if indexPath.section == enableSection {
cell = tableView.dequeueReusableCellWithIdentifier(enableAlarmCellIdentifier,forIndexPath: indexPath)
let myCell = cell as! SwitchTableViewCell
myCell.theSwitch.on = alarmEnabled
myCell.setCallback({[unowned self] (boolValue:Bool) in
self.alarmEnabled = boolValue
})
}
}
...
}
As advantages I see following :
No need of delegate
No method called where I need to determine which value I need to update (I have multiple instances of my cell for different variables)
I can't grasp the possible drawbacks my idea could have and if in overall it's a bad or a good idea.
Personally I am kinda old school and simply prefer the delegation pattern over closures.
But for your question ... what you suggest is exactly what closures are made for. Just go for it.
You simply hand over to another class' object some piece of code (or the reference to some subroutine's entry point respectively) that you want to be executed when some event occours. That's what it's made for and that's what you are doing.

Find out UITableViewCells with detailTextLabel [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'd like to find out all UITableViewCells (number varies) which have an detailTextLabel with the text "Done" in it. How can I do this in Swift?
You should not do this. Neither in Swift nor in any other language. You should query the dataSource because that is where the true state is stored. If you scroll a cell offscreen it get's reused, and the text gets set to something else. You can't rely on that information. Even worse, if you rely on texts in your cell you never get the whole picture about your dataSource, because the cells that are offscreen simply don't exist.
Here's what you should do: Somewhere in your code you set the text to "Done" depending on the state of an object. Use the same decision to find all objects that are done.
For example, if your object has an isDone getter, you hopefully use something like this to create the cell:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ProjectCell", forIndexPath: indexPath) as ProjectCell
let project = allProjects[indexPath.row]
if project.isDone {
cell.detailTextLabel?.text = "Done"
}
else {
cell.detailTextLabel?.text = nil
}
return cell
}
as you can see you decide depending on isDone if the "Done" text will be displayed.
So you can create a function that uses the same test to create an array that contains only projects that are done.
func projectsThatAreDone(allProjects: [Project]) -> [Project] {
let matchingProjects = allProjects.filter {
return $0.isDone
}
return matchingProjects
}
and you then use let doneProjects = projectsThatAreDone(allProjects)

Resources