I've added a UITableView into my app. This tableview includes cells, which shows a few custom editing buttons if they're swiped to the left (via this function: editActionsForRowAtIndexPath). I'd like to find out which UITableViewCell is swiped to the left or shows up the custom editing options and set a default text as a detailText label into this cell.
For further explanation:
I have a few UITableViewCells. The user swipes one of these cells. Now the cell is in the editing mode and shows the editing option, which I've added (named "Date"). The user press this button/option (Date). Now a datePicker is poping up. The user chose a date. This date is written in a label. This dateLabel should be transmitted into the detailTextLabel of the cell which was swiped. The problem is that I don't know how to transmit the label with the date to the detailTextLabel of the cell which was swiped.
I hope someone can help me. I am coding with Swift.
This is my code for the custom options if the UITableViewCell is swiped to the left:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
let editingCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
let date = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Date", handler: { (action, indexPath) -> Void in
self.showSideBar(true)
self.delegate?.sideBarWillOpen?()
self.isEditingStyle = true
})
date.backgroundColor = UIColor(red: 0.204, green:0.667, blue:0.863, alpha: 1.0);
return [date];
}
date picker:
func datePickerChanged(datePicker:UIDatePicker) {
var dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
var strDate = dateFormatter.stringFromDate(datePicker.date)
dateLabel.text = strDate
}
adding date into detailTextLabel:
lastEditedCell?.detailTextLabel?.text = dateLabel
You can keep track of the lastEditedCell in tableView(tableView:, editActionsForRowAtIndexPath indexPath:) function
var lastEditedCell:UITableViewCell? // property of the class
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
let editingCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
lastEditedCell = editingCell
//Your Code
}
After you set the date from picker view, you can set in the callback function.
lastEditedCell?.detailTextLabel.text = date
Related
I am trying to get my table view to update when I add a new cell to my SQLite Table. However, as of now, when I add a new cell to the SQLite Table and call reloadData, nothing updates or happens. My UITableView is embedded into my Main View Controller so that might be part of the issue. I also feel as if this may be an issue with the tableView.dataSource or something. I am not sure. I am very new to swift.
I have tried calling the reloadData from the UITableViewController file and from the UIViewController which contains the button that is supposed to add data and then update the Table. Neither have worked. I also tried to substitute it with tableView?.beginUpdates() and tableView?.endUpdates()
My button code (part of button script):
#IBAction func addTask(_ sender: Any) {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mmZZZZZ"
let taskDateFormatted = dateFormatter.string(from: taskDate.date)
let newTask = Task(title: taskTitle.text!, description: descriptionTextView.text,
date: taskDateFormatted)
let instSQLiteData = SQLiteData()
let instTaskTableVC = TaskTableVC()
instSQLiteData.uploadData(newTask.title, newTask.description, newTask.date)
instTaskTableVC.taskTable?.reloadData()
dismiss(animated: true, completion: nil)
}
My UITableViewController script/class (part of tableview script):
class TaskTableVC : UITableViewController {
#IBOutlet var taskTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.taskTable.dataSource = self
self.taskTable.delegate = self
}
How my UITableViewController loads data (part of tableview script):
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let instSQLiteData = SQLiteData()
return instSQLiteData.getRowCount()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let instSQLiteData = SQLiteData()
let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath)
cell.textLabel?.text = instSQLiteData.getTasksArray()[indexPath.row]
return cell
}
Once the button is pressed I just want the table to update but I cannot get it to work even though I have tried to follow a ton of other questions with the same topic. Much thanks!
I have a UITableView that uses custom UITableViewCell. cell contains a UITextField. like in image below.
each TextField is configured in the cellForRowAtIndexPath method. eg. textContentType, keyboardType etc.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ReuseCellIdentifier", for: indexPath) as! FormTableViewCell
let inputItem = inputItems[indexPath.row]
cell.titleLabel.text = inputItem.title
cell.inputTextField.placeholder = inputItem.placeholder
cell.inputTextField.textContentType = inputItem.contentType
cell.inputTextField.keyboardType = inputItem.keyboardType
cell.inputTextField.isSecureTextEntry = inputItem.isSecure
return cell
}
However when editing last TextField(Re-Password) it shows email addresses as autofill suggestions although the textContentType is set to newPassword.
if tapped on one of the suggestions, the email(3rd textField) is populated with the email. not the textField that was being edited. also 4th textfield(password) becomes first responder.
weirdly, if I remove this line, the problem goes away
cell.inputTextField.isSecureTextEntry = inputItem.isSecure
InputItem class,
class InputItem:Mappable {
var title:String?
var placeholder:String?
var contentType:UITextContentType?
var keyboardType:UIKeyboardType?
var isSecure:Bool = false
}
// you can set autocorrectionType to turn on/off suggestions
// UITextAutocorrectionType can be .no or .yes
cell.inputTextField.autocorrectionType = inputItem.autocorrectionType // set .no to turn off suggestions
I am new to swift, and I am trying to take text from one textfield and values from two other text fields (one value from each text field) on a ViewController, and then when a button is pressed, have all three pieces of information displayed horizontally in a cell in a tableview.
This is an example of what I am trying am trying to do:
I would like the data from text fields one, two and three to be displayed in labels one, two and three, once the button is pressed.
#IBAction func btn_reload(sender: AnyObject)
{
/*lbl1.text = txtfield1.text!
lbl2.text = txtfield2.text!
lbl3.text = txtfield3.text!*/
var arrmute: [AnyObject] = [AnyObject]()
var arrmute2: [AnyObject] = [AnyObject]()
var arrmute3: [AnyObject] = [AnyObject]()
arrmute.append(txtfield1.text!)
arrmute2.append(txtfield2.text!)
arrmute3.append(txtfield3.text!)
self.tbl_out.reloadData()
}
First setup set delegate and datasource of UITabelView in your storyboard.
Give reuseIdentifier of row as given in code: cell
Make outlet of your UITableView.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return arrmute.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell: UITableViewCell
if cell == nil
{
cell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
}
cell.lbl1.text = arrmute[indexPath.row]
cell.lbl2.text = arrmute2[indexPath.row]
cell.lbl3.text = arrmute3[indexPath.row]
return cell
}
Ive seen a few questions here about this but no defitnive answer Im using an up to date version of Xcode and swift...
Im trying to work with two table views in one view controller here is my cellForRowIndexPath function
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell!
if(tableView == self.allTableView){
cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! BMRadioAllTableViewCell
cell.mixImage.image = mixPhotoArray[indexPath.item]
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
cell.mixDateLabel.text = dateFormatter.stringFromDate(mixDateArray[indexPath.item])
}
if(tableView == self.featuredTableView){
// SET UP THE NEXT TABLE VIEW
}
return cell
}
Im getting the error "Value of type UITableViewCell has no member "xxxx" so its obviously not registering the change to cell I'm making in the if statement.
I have tried various other ways, like declaring the variable within the if statement and returning it there. But you get the error "Missing return in a function expected to return UITableViewCell" since you need to get it outside the if statement.
If you have two different cell types for two different tables, you should make your code look something like this:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if(tableView == self.allTableView){
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! BMRadioAllTableViewCell
cell.mixImage.image = mixPhotoArray[indexPath.item]
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
cell.mixDateLabel.text = dateFormatter.stringFromDate(mixDateArray[indexPath.item])
return cell;
} else {
var cell = ...
// SET UP THE NEXT TABLE VIEW
return cell
}
}
There's no need to have a single generic cell variable that handles both tables.
The error doesn't really have to do with you trying to configure two table views.
Even though you're casting the result of dequeueReusableCellWithIdentifier:forIndexPath: to BMRadioAllTableViewCell, you are then assigning it to a variable of type UITableViewCell!. As such, it will be a compiler error for you to access fields of BMRadioAllTableViewCell.
You would either need to change the cell type to BMRadioAllTableViewCell, or have a locally scoped variable of the correct type that you configure and then assign to cell:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell!
if(tableView == self.allTableView){
let bmRadioAllCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! BMRadioAllTableViewCell
bmRadioAllCell.mixImage.image = mixPhotoArray[indexPath.item]
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
bmRadioAllCell.mixDateLabel.text = dateFormatter.stringFromDate(mixDateArray[indexPath.item])
cell = bmRadioAllCell
}
if(tableView == self.featuredTableView){
// SET UP THE NEXT TABLE VIEW
}
return cell
}
I've not been able to figure out how to do the following in Swift and looking for pointers.
I'm pulling string values from Core Data and displaying them in a UITableView...that's working and displaying all entries. I now want to 'group' these values by date created (also stored in Core Data) but am having a hard time implementing this group header...here's what I have:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var sound = self.sounds[indexPath.row]
var cell = UITableViewCell()
// Convert Date to String
var formatter: NSDateFormatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd-HH-mm-ss"
let dateTimePrefix: String = formatter.stringFromDate(sound.dateSaved)
// Display the following in each rows
cell.textLabel!.text = sound.name + " Saved: " + dateTimePrefix
return cell
}
Could someone point me in the right direction as to how to implement 'headers'? I already have the tableView in my Main.storyboard setup to 'Grouped' as a style.
--- Update
Thanks for the response below but, unfortunately, the examples are in Obj-C and I'm shooting for swift.
To expand, I have the following retrieving data from Core Data and displaying all in UITableView:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.dataSource = self
self.tableView.delegate = self
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
var context = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext!
var request = NSFetchRequest(entityName: "Sound")
self.sounds = context.executeFetchRequest(request, error: nil)! as [Sound]
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.sounds.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell")
var sound = self.sounds[indexPath.row]
// Convert Date to String
var formatter: NSDateFormatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd # HH:mm:ss"
let dateTimePrefix: String = formatter.stringFromDate(sound.dateSaved)
// Display the following in each rows
cell.textLabel!.text = sound.name // Sound Name
// Display the following as each subtitles
cell.detailTextLabel!.text = dateTimePrefix // Sound Duration (Currently 'date')
return cell
}
Could someone point me in the right direction as to how I go about 'grouping' each by month with a 'month' header using sectionNameKeyPath, I believe? Specifically, which piece of code would need to be modified to break list into 'sections'.
Here are some pointers:
You need to use an NSFetchedResultsController ("FRC") - check out the documentation here. You will see that you specify the sectionNameKeyPath when initialising the FRC.
There is boilerplate code for updating a tableView using an FRC. The easiest way to get this, and observe how the FRC works, is to create a project using Apple's Master/Detail application template, ensuring you select the "Use Core Data" option. Play with it in that project to see how it works, and then cut/paste into your own project.
In your case, you want to the month (and presumably year?) as the section name. There are a few ways to do that, but the easiest is to create a function (eg. sectionIdentifier) in your Sound class which returns a string with the section name, in the format you desire, derived from the dateSaved. Then specify sectionNameKeyPath:sectionIdentifier when initialising the FRC.