This is my app:
When i press the Edit button (''Rediger''), i get the following:
So my question is: How do i make the round red circle and the disclosure indicator hidden while the tableview is being edited? Both the circle and the disclosure indicator are imageViews.
Here is the code for the custom cell (i edited out the unnecessary parts):
class KundeavisCell: UITableViewCell {
#IBOutlet weak var unreadImage: UIImageView!
#IBOutlet weak var disclosureIndicatorImage: UIImageView!
}
And the view controller with the table:
class KundeaviserVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var redigerOutlet: UIBarButtonItem!
var stores = ["Rema 1000", "Coop Obs", "Coop Extra"]
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "KundeavisCell", for: indexPath) as! KundeavisCell
// Here i edit the cell
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return stores.count
}
#IBAction func tableViewEditingPressed(_ sender: Any) {
if tableView.isEditing {
tableView.setEditing(false, animated: true);
redigerOutlet.style = UIBarButtonItemStyle.plain;
redigerOutlet.title = "Rediger";
} else {
tableView.setEditing(true, animated: true);
redigerOutlet.title = "Ferdig";
redigerOutlet.style = UIBarButtonItemStyle.done;
}
}
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let itemToMove = stores[sourceIndexPath.row]
stores.remove(at: sourceIndexPath.row)
stores.insert(itemToMove, at: destinationIndexPath.row)
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.none
}
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
}
I know i can indent the images to the left by setting constraints on them, but i want to hide them completely. I found a question about it: Link but unfortunately it was written 5 years ago and in Objective-C.
Any help will be highly appreciated, thanks!
That code you reference is still valid to now. You already have the Custom implementation of the UITableViewCell so now implement the SetEditing function and in the implementation hide/shows your images.
override func setEditing(_ editing: Bool, animated: Bool) {
unreadImage.isHidden = editing
disclosureIndicatorImage.isHidden = editing
}
That should work.
Related
I'm trying to create an App but I'm struggling with a simple problem: How can I add a delete button to my custom cells?
I've created a NewCocoaTouchClass
I've created my custom design (added also a button for every cell) and provided the Outlets in the TableViewCellController
I managed to implement my custom cell to another viewController
I created a button on my viewController
I'd like that when the user taps on my new button, cell buttons will appear, and then I can delete cells singularly. When I create the IbAction I can't retrieve the cell code because the cell is defined only in my tableViewCode.
Thank in advance
Ps: I also implemented deleting cells by swipe but my custom cell design is incompatible with the standard rectangular delete option (this is awful).
TableViewCellController
import UIKit
class CustomTableTableViewCell: UITableViewCell {
static let identificatore = "CustomTableTableViewCell"
static func nib() -> UINib {
return UINib(nibName: "CustomTableTableViewCell", bundle: nil)
}
#IBOutlet weak var ImmagineCella: UIImageView!
#IBOutlet weak var TestoCella: UILabel!
#IBOutlet weak var Button: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
ViewController
import UIKit
class MaterieViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var materie : [String] = ["zoifvdhfdv", "szvzv", "zdvzfv", "zfdvbfdb", "bfzdfb"]
#IBOutlet weak var TableViewMaterie: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
TableViewMaterie.register(CustomTableTableViewCell.nib(), forCellReuseIdentifier: CustomTableTableViewCell.identificatore)
TableViewMaterie.delegate = self
TableViewMaterie.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return materie.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableTableViewCell.identificatore, for: indexPath) as! CustomTableTableViewCell
cell.TestoCella.text = materie[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 67.83
}
#IBAction func EditButton(_ sender: UIButton) {
}
}
This is the code I use in my project
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String?
{
return "Delete"
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
//Add your code
}
}
You can write with add target
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableTableViewCell.identificatore, for: indexPath) as! CustomTableTableViewCell
cell.TestoCella.text = materie[indexPath.row]
cell. Button.tag = indexPath.row
cell. Button.addTarget(self, action: #selector(buttonClicked(sender:)), for: .touchUpInside)
return cell
}
func buttonClicked(sender: UIButton) {
let buttonRow = sender.tag
print(buttonRow)
}
I am asked to do optimise my swift code especially when it comes to UI Delegate methods.
Scenario: I have UITableView in five UIViewControllers, in each view controller I am using UITableView delegate methods due to which my code is repeating. So how can I optimise this thing?
Below is the structure of code: You can see delegate method code is repeating
class FirstViewController: UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var userArray = [UserModel]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
// register cell according to model (Dynamic Cells)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell01", for: indexPath)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
}
class SecondViewController: UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var productArray = [ProductModel]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
// register cell according to model (Dynamic Cells)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return productArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell01", for: indexPath)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
}
I'm making an alarm function similar to the iPhone alarm app.
When setting the alarm day, I am writing code to check the day of the week.
class DaySelectCell: UITableViewCell {
#IBOutlet weak var dayLbl: UILabel!
#IBOutlet weak var checkView: Checkbox!
}
import UIKit
class DaySelectViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
let days = ["일요일마다","월요일마다","화요일마다","수요일마다","목요일마다","금요일마다","토요일마다"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
}
extension DaySelectViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return days.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DaySelectCell") as! DaySelectCell
cell.dayLbl.text = days[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "DaySelectCell") as! DaySelectCell
}
}
The part I want to ask is didSelectRowAt
I want to make a checkView.isSelectd of that cell to be true when I click on a certain day cell.
You have to manage datasource to hold the selected value, So you can pretend which index is selected.
var selectedDays: [Int] = []
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell.accessoryType = selectedDays.contains(indexPath.row) ? .checkmark : .none
}
Now in didSelectRowAt method write this code
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let index = selectedDays.firstIndex(where: { $0 == indexPath.row }) {
selectedDays.remove(at: index)
} else {
selectedDays.append(indexPath.row)
}
tableView.reloadData()
}
I am trying to make a FAQ view controller using table view, I need little bit fix in the UI. here is the display of my FAQ VC right now
(please ignore the red line)
as we can see, basically there are 2 row height, 80 & 160. if the row is tapped (selected) the row height will expand from 80 (yellow line) to 160 (purple line).
I want to make the row height under the last question is still 80 not 160. I have tried but I can't set the row below the last question. here is my code I use
class FAQVC: UIViewController {
#IBOutlet weak var retryButton: DesignableButton!
#IBOutlet weak var tableView: UITableView!
var FAQs = [FAQ]()
var selectedIndexs: [IndexPath: Bool] = [:]
override func viewDidLoad() {
super.viewDidLoad()
getFAQData()
}
}
extension FAQVC : UITableViewDelegate, UITableViewDataSource {
// MARK: - Table View Delegate and Datasource
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return FAQs.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FAQCell") as! FAQCell
cell.FAQData = FAQs[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if self.cellIsSelected(indexPath: indexPath) {
return 160
} else {
return 80
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let isSelected = !self.cellIsSelected(indexPath: indexPath)
selectedIndexs[indexPath] = isSelected
tableView.beginUpdates()
tableView.endUpdates()
}
func cellIsSelected(indexPath: IndexPath) -> Bool {
if let number = selectedIndexs[indexPath] {
return number
} else {
return false
}
}
}
Please put this code in your viewDidLoad() method of your controller.
YOUR_TABLE_VIEW.tableFooterView = UIView(frame: .zero)
this will remove extra separators.
Quickest way to do this would be to add an extra empty cell at the end with row height 80
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return FAQs.count + 1
}
Also, make sure you make a change to cellForRowAt method to accommodate this :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < FAQs.count {
let cell = tableView.dequeueReusableCell(withIdentifier: "FAQCell") as! FAQCell
cell.FAQData = FAQs[indexPath.row]
return cell
}
return UITableViewCell()
}
EDIT :
I just read that you don't really require separators after the last cell. In that case look here https://spin.atomicobject.com/2017/01/02/remove-extra-separator-lines-uitableview/
Here is the code from my custom cell class:
import UIKit
class CustomOrderTableViewCell: UITableViewCell {
#IBOutlet var MealName: UILabel!
#IBOutlet var MealPrice: UILabel!
#IBOutlet var MealDescription: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func deleteMeal(sender: AnyObject) {
}
}
Here are the table view related functions:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mealArray.orderedMeals.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
print("in")
var cell = tableView.dequeueReusableCellWithIdentifier("orderCell", forIndexPath: indexPath) as! CustomOrderTableViewCell
cell.MealName.text = mealArray.orderedMeals[indexPath.row].mealName
cell.MealDescription.text = mealArray.orderedMeals[indexPath.row].mealDescription
let price = NSString(format: "%.2f", mealArray.orderedMeals[indexPath.row].mealPrice) as String
cell.MealPrice.text = "R" + price
return cell
}
The problem is that nothing gets displayed in the table view and func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell is never called.
Any solutions? Thanks
If func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell is never called that means you have not connected your UITableViewDataSource in IB correctly. Make sure that you connect the dataSource property with your ViewController. Also check that all classes are set for your ViewController, TableView and the Cell itself as this another common mistake.