I have a UITableView with 2 sections, in the first one there is the cells that each represent the different item from an array, and the second one calls a UIAlertController with a textfield. I want whatever I write in the textfield to show in the first section of the tableView. My code currently is:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.section {
case 0:
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
UserDefaults.standard.set(selectedCaseSolutionsForCell[indexPath.row], forKey: "ollShowAlg\(selectedCaseID)")
print("OLL Case with ID \(selectedCaseID) had its main algorithm changed to \(selectedCaseSolutionsForCell[indexPath.row])")
let newMainSolve : String = UserDefaults.standard.string(forKey: "ollShowAlg\(selectedCaseID)")!
print("THE ALGORITHM IS NOW \(newMainSolve)")
case 1:
tableView.cellForRow(at: indexPath)?.accessoryType = .none
let alert = UIAlertController(title: "Add New Algoritm", message: "", preferredStyle: .alert)
alert.addTextField()
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
let textField = alert?.textFields![0] // Force unwrapping because we know it exists.
print("Text field: \(textField!.text!)")
}))
present(alert, animated: true)
default:
return
}
}
How can I add the textfield input to the array and then show that at the end of the UITableView? This question is not a duplicate as I'm not using a custom cell and don't have an IBOutlet or IBAction for it.
I'll assume the table's data source is an array of string named data. Something like this:
fileprivate var data: [String] = []
Then all you have to do after this line print("Text field: \(textField!.text!)") is add the following:
self.table.beginUpdates()
self.data.append(textField!.text!)
self.table.insertRows(at: [IndexPath(item: self.data.count - 1, section: 0)], with: .bottom)
self.table.endUpdates()
Related
I have converter application with tableView with cells which contains results of conversion.
For example you entered 5 kilometers and in tableView cells for Meters shows 5000 and so on.
I want to make UIAlert with full result when press to one of cells.
So i want to se my result for Meters and i press on meters cell. How could i make it?
I tried to make a additional variables and connect them to Alert but the value still shows not the cell that i choose but the first cell at the table that shows at the moment...
Does anyone have ideas?
let cell1 = tableView.dequeueReusableCell(withIdentifier: "resultCell") as! ResultTableViewCell
let item = converter[indexPath.row]
cell1.nameResult.text = item.title
cell1.subtitleResult.text = item.subtitle
//MARK: - Форматтер для результатов
let formatter = NumberFormatter()
formatter.locale = Locale.current
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 3
formatter.maximumFractionDigits = maxdigits
if converterVal == NSLocalizedString("Километр", comment: "") {
cell1.labelResult.text = formatter.string(from: NSDecimalNumber(value: inputValue).multiplying(by: NSDecimalNumber(value: item.kfKilometer)))
resultVar = cell1.labelResult.text!
resultName = cell1.nameResult.text!
return cell1
} else if converterVal == NSLocalizedString("Метр", comment: "") {
cell1.labelResult.text = formatter.string(from: NSDecimalNumber(value: inputValue).multiplying(by: NSDecimalNumber(value: item.kfMeter)))
resultVar = cell1.labelResult.text!
resultName = cell1.nameResult.text!
return cell1
} else {
cell1.labelResult.text = formatter.string(from: NSDecimalNumber(value: 0))
return cell1
}
nameResult - is name of converted value
and labelResult - is result of conversion
and for every cell i have if else statement.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView == self.tableView2 {
let alertController = UIAlertController(title: NSLocalizedString("\(inputValue) \(detailLabel) is:", comment: ""), message: NSLocalizedString("\(resultVar) \(resultName)", comment: ""), preferredStyle: .alert)
let OKAction = UIAlertAction(title: NSLocalizedString("Спасибо", comment: ""), style: .default) { action in
// ...
}
alertController.addAction(OKAction)
self.present(alertController, animated: true) {
// ...
}
}
// tableView.deselectRow(at: indexPath, animated: true)
}
And i want to show more closely this labels in Alert but only for every cell it must be own...
May be you need to modify you method like below
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView == self.tableView2 {
// get your selected row data
let item = converter[indexPath.row]
//use item.title or item.subtitle instead of label
let alertController = UIAlertController(title: NSLocalizedString("\(inputValue) \(detailLabel) is:", comment: ""), message: NSLocalizedString("\(resultVar) \(resultName)", comment: ""), preferredStyle: .alert)
let OKAction = UIAlertAction(title: NSLocalizedString("Спасибо", comment: ""), style: .default) { action in
// ...
}
alertController.addAction(OKAction)
self.present(alertController, animated: true) {
// ...
}
}
}
Let me explain something : cellForRowAt indexPath this method create cell and fill data whatever you pass in it. so if you assign value resultVar in this method, it will give you wrong value.
didSelectRowAt called when you click on cell row, so assign value resultVar in this method and do your operations or whatever you want
Access cell instead when you click on row
if let cell = tableView.cellForRow(at: indexPath) as? YourCellClass {
// access your cell label and get values
print(cell.titleLable.text!)
}
My code is this:
let alrController = UIAlertController(title: "Membri", message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
tableView.backgroundColor = UIColor.white
alrController.view.addSubview(tableView)
let cancelAction = UIAlertAction(title: "Esci", style: UIAlertActionStyle.cancel, handler: {(alert: UIAlertAction!) in})
alrController.addAction(cancelAction)
self.present(alrController, animated: true, completion:{})
I want to populate (but I don't know how) the tableView with this values in my array: names["name1","name2","name3"]
Can someone help me?
To populate an action sheet, you don't add a tableView. Instead, you simply add the actions and it will create and manage the tableView privately.
For a recent tutorial, see UIAlertController Examples
The idea is that you'd create an UIAlertAction for each String in your array, including a closure for what to do when user taps that action row.
for name in names
{
let namedAction = UIAlertAction(title: name, style: .default)
{ (action) in
// do something when this action is chosen (tapped)
}
alrController.addAction(namedAction)
}
You need to implement the following tableView dataSource methods in order to populate this data and also set tableView datasource to alertController like below:-
tableView.dataSource = alertController
TableView DataSource method
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell: yourCustomCell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as? yourCustomCell
else {
fatalError("yourCustomCell not found")
}
cell.textLabel.text = names[indexpath.row]
return cell
You can use custom UIViewController transition to achieve this kind of functionality.
This link: https://github.com/pgpt10/Custom-Animator will give you an idea of how you can achieve that.
I have a tableView in a view controller where I display data from an API call, now if the user selects a tableview cell(say row 2 in the TableView), I want to fetch that data(Data in row 2 of TableView) and display it in the Textfield on the same screen. What is the best way to do this?
The simplest way is you can show show the UIAlertController with textField on didSelect of tableViewCell.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let alert = UIAlertController(title: "Edit Data", message: "Edit corresponding detail", preferredStyle: .alert)
alert.addTextField { (textField) in
textField.placeholder = "Enter name"
textField.text = yourArray[indexPath.row]
}
alert.addAction(UIAlertAction(title: "Edit", style: .default, handler: { (action) in
//Edit data on array
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true)
}
You can try this one, When user select's particular UITableViewCell then that cell contents will be show in UITextField.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell= tableView1.cellForRow(at: indexPath)
if let txtVal = cell?.textLabel?.text {
textField.text = txtVal
}
}
You have data from from webservice which you are displaying on your UITableview say arrWebServiceData. and you have index of row where user clicked on say index. Simplest way is to get Data from arrWebServiceData at index and use it to display on test field.
for example:
NSArray *arrWebServiceData; //you are storing data from Wevserice here.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let index = indexPath.row;
let dataAtIselectedIndex = yourArray[indexPath.row] ;
//If data is string, dirctly display it on text field,or if its dictionary, set object of diction on your text field.
}
Well i know these types of questions are answered by SO before, but mine is little different so please read it.
I am using a button inside tableview cell. On click of button i am showing an AlertViewController with list of actions. On selecting action my button text and my custom model class propery is changed.
Button text is changing on button click. But my problem is cell not storing button state. If i change button of 1st cell and then click on second cell button all other buttons back to its default text.
please see this video
Here is my code
setting cell data
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("dbColumns", forIndexPath: indexPath) as! CustomColumnTableViewCell
let column = columns[indexPath.row]
cell.dbColumnName.text = column.name
cell.dbColumnOrder.titleLabel?.text = column.order
cell.dbColumnOrder.tag = indexPath.row
print(columns)
cell.dbColumnOrder.addTarget(self, action: #selector(ViewController.showAlert(_:)), forControlEvents: UIControlEvents.TouchUpInside)
return cell
}
Action on button click
//MARK:Show Alert
func showAlert(sender:UIButton){
let alert = UIAlertController(title: "Column Order", message: "Please select column order", preferredStyle: .ActionSheet)
let index = sender.tag
let indexPath = NSIndexPath(forRow: index, inSection: 0)
alert.addAction(UIAlertAction(title: "None", style: .Default, handler: { (action) in
//execute some code when this option is selected
self.columns[index].order = "None"
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}))
alert.addAction(UIAlertAction(title: "Assending", style: .Default, handler: { (action) in
//execute some code when this option is selected
self.columns[index].order = "Assending"
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}))
alert.addAction(UIAlertAction(title: "Desending", style: .Default, handler: { (action) in
//execute some code when this option is selected
self.columns[index].order = "Desending"
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
Please hemp me.
In cellForRowAtIndexPath method Set button text like this way
First remove this
cell.dbColumnOrder.titleLabel?.text = column.order
Replace this
cell.dbColumnOrder.setTitle("\(column.order)", for: .normal)
And one more thing you need to increase cell.dbColumnOrder width.
Hope it works
I'm a beginner of Swift, and I searched a lot of stuffs, but couldn't figure out and decided to post my first question ever here.
I have a table view to show tweets by using twitter fabric and I use UITableViewRowAction to present two options to users when a swipe is done on a row, "funnelOne" and "funnelTwo", to categorize their tweets by adding tags to each tweet.
In the view controller, I add two functions to make an alert and get a value of 'funnelTag' to store it to my core data.
However, I am not sure if I can correctly store the number to the core data because somehow different cell would be deleted if I push one of swipeable buttons. I know I can write a code within 'func tableView' to delete the row, but how I can get access from out of 'func tableView' to delete the row successfully??
If it can be resolved, I should be able to successfully store the value to my core data.
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath) as? CustomTableViewCell
let funnelOne = UITableViewRowAction(style: .Default, title: "funnel") {
(action, indexPath) -> Void in
funnelTag = 1 // funnelTag is Int I want to store in my Core Data
cell!.tag = funnelTag
// self.tweets.removeAtIndex(indexPath.row) - I know this is working
tableView.setEditing(false, animated: true)
}
let funnelTwo = UITableViewRowAction(style: .Default, title: "funnel") {
(action, indexPath) -> Void in
funnelTag = 2
cell!.tag = funnelTag
tableView.setEditing(false, animated: true)
// self.tweets.removeAtIndex(indexPath.row)
}
These are two functions I add. if I implement these functions, top row would be deleted even though I want to delete other row... the first function, funnelTweet() is properly working, but the second function does not seem to work correctly..
func funnelTweet(cell: CustomTableViewCell){
let index: Int = cell.tag
if SettingStore.sharedInstance.isNoAlert(){
self.submitFunnel(index, cell: cell)
} else {
self.alert = UIAlertController(title: NSLocalizedString("stock_confirm_funnel", comment: ""), message: nil, preferredStyle: .Alert)
self.alert!.addAction(UIAlertAction(title: NSLocalizedString("common_ok", comment: ""), style: .Destructive) { action in
self.submitFunnel(index, cell: cell)
})
self.alert!.addAction(UIAlertAction(title: NSLocalizedString("common_cancel", comment: ""), style: .Cancel) { action in
cell.moveToLeft()
})
self.presentViewController(self.alert!, animated: true, completion: nil)
}
}
func submitFunnel(index: Int, cell: CustomTableViewCell){
var tweet = self.tweets[index]
// store to local storage
TagStore.sharedInstance.saveData(tweet.createdAt, funnelTag: funnelTag, id: tweet.tweetID)
self.tweets.removeAtIndex(index)
self.tableView!.reloadData()
}
Thank you for your help!
In the Second function you have not initialized the index before using it.
func submitFunnel(index: Int, cell: CustomTableViewCell){
// Initialize index here before using it in the next statement.. that is give it a value, otherwise it will return nil
var tweet = self.tweets[index]
// store to local storage
TagStore.sharedInstance.saveData(tweet.createdAt, funnelTag: funnelTag, id: tweet.tweetID)
self.tweets.removeAtIndex(index)
self.tableView!.reloadData()
}