iOS Table cell styling - ios

In my iOS - swift project I need my table cells to look like this. I can get the multi select option by making the table editable. What I need to know is what are the ways that I can design a cell to look like this? How can I add that colored border at the bottom and how can seperate the cells to look like this?
Thanks

The cells you show in your question are custom cells. To make that, you would need to design those cells yourself with views, labels, buttons, etc. There is no default/boilerplate code that can do this for you; you will need to implement it yourself.

You must create and implement this custom cell.
Create a New file, Cocoa Touch class, on next page select "subclass of: UITableViewCell" and name "CustomCell"
Create a New file, select User Interface (under iOS) and select Storyboard, and Name something like "MyCustomCell". On this new storyboard drag a Table View Cell. Select this cell, and in identity inspector make the class = to the name of your "CustomCell" cocoa touch class file. Then go to Attributes Inspector and fill in "identifier" with "cell"
NOW
In your TableViewController file
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: CustomCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! CustomCell
// Here's where you set your CustomCell properties like label title, images, backgrounds
return cell;
}
I don't know yet how to make the cells separated, but as to the border at the bottom just go to your "MyCustomCell" xib and add a view at bottom and change its background.
Maybe to get the space in-between you can use some sort of Layer (CAlayer).

Related

Why UITableViewCell is not accessible (for VoiceOver)

I'm not trying to solve any problem. Of course you can set isAccessibilityEnabled = true and it works. My question is: why is it turned off by default and there is no appropriate section in the interface builder. It seems for me like it's not recommended to make UITableViewCell subclasses accessible. Is there any better ways to make cells accessible? I mean to make a cell as one accessibility element which will contain all the info for VoiceOver.
why is it turned off by default
A UITableViewCell may be seen as a container inside which many elements are embedded (buttons...) and, as is, you can't have simultaneously a parent view (the table view cell) and its child views (label, button...) that are both accessible with VoiceOver: either your cell can be selected or its content.
By default, the content must be seen by VoiceOver: add two buttons in your cell and you'll see the difference by enabling/disabling the accessibility of the cell.
Is there any better ways to make cells accessible? I mean to make a cell as one accessibility element which will contain all the info for VoiceOver.
To reach your goal, the best way is to make your cell accessible while providing an accessibilityLabel and adding custom actions if many actions are planned in this cell (with buttons for instance).
Following this rationale improves the user experience: one unique selection with possible actions.
If you don't want the elements inside each cell to be read out, just define each one of your cells as follows:
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier",
for: indexPath)
cell.isAccessibilityElement = true
cell.accessibilityLabel = "APPEND YOUR LABELS HERE"
// Add everything you need to construct your cell here.
return cell
}
That's the simplest configuration but you may decide to reach every elements in the cell and, in this case, it's quite different: see this answer or this one if you need some implementation examples for this.
Personnally, I always subclass the table view cell to define its trait, its array of accessiblity elements and its potential actions so as to control the way information are provided to the VoiceOver user: I find it very flexible even if it seems to be tedious at first sight. ;o)

Is it language appropriate to layer a UIButton over a UILabel in Swift 3.0?

My question is this: Is this following approach to making a UILabel tap sensitive stylistically acceptable in the Swift 3 language? I'm tempted to say "if it compiles it flies" but I don't want to get in the habit of using this "short cut" if it is going to bite me later on. Further, if it is acceptable, are there some drawbacks to using this method that aren't obvious to a newcomer like me?
Please note that I am not looking for a way to implement code, I have one. I am asking if the solution I have is acceptable from a language style perspective.
I've been trying to get a UILabel to accept a TapGesture when inside a table cell for 2 days now and whatever method I try, there is always some sort of error even if it will compile. On a hunch, I went to my storyboard for the table view and added a button on top (not stacked, or aligned, or anything like that – actually occupying the same 2D space on the story board) within the prototype cell. I deleted the button text, linked it to the table view cell code and implemented some basic functionality to change the text on the UILabel to red and back. All of this functions exactly like I expected. I click the button and the text changes from black to red, and back when clicked again. The UILabel text is static in the table cell on a white background and my real function isn't going to change the text, it is going to alter another view through delegation from that view.
Why do it this way? Even if I check the UILabel use interaction box and follow some of the other questions and answers here to make it tap-able, I cannot control+drag the UILabel to the table view cell and make an action, the option simply doesn't exist in the pull down menu. It is available if I control+drag the UILabel to the table view controller. This makes a kind of sense to me because it is the table view controller that senses touch (right?). But, on the other hand, I have a switch in the table view cell that works just fine when I follow the answer to this question. Simple functionality of the storyboard-code interation (control+drag) is preventing me from getting what I want. Maybe control+drag should be allowing me to make an action and doesn't? I don't know. I don't want to use a UIButton alone because the text scaling feature of UILabel is really handy.
If you just want to recognize taps on the table cell, make the class the delegate of the table view
tableView.delegate = self
and implement
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//your code here
}
I'd also appreciate you taking the time to read a bit more about UITableViews. Every UITableViewCell has a label by itself. Consider the following code:
tableView.dataSource = self // this code will ideally be in init
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "lovCell")
cell.textLabel?.text = dummyData[indexPath.row]
return cell
}

How to assign a specific ViewController to a UIView (in UICollectionView)?

I searched the web for hours but I can't find a solution to my problem.
I have a View in my storyboard that contains a UICollectionView. I've set the cells of the UICollectionView to be really big (only one can appear on the screen, you have to swipe horizontally to see the others). In my application, I use this layout to ask the user some questions, one after another. The user can respond to those questions by touching buttons, move around a map, select a date, etc... Each questions have the same layout; they are displayed in a box, with a title label and a button. That's why I chose to use a UICollection View.
I want to display a specific view (the options that allows the user to answer (buttons, Map, DatePicker, etc..)) for each questions in the blue rectangle (see picture below).
A screenshot of my view
My idea was to create multiple ViewControllers in my StoryBoard and be able to tell : "ok, for the first question (first cell), put the view XXX in the container, for the second, put the view YYY, etc...".
How can I do this ?
I've tried to add a ContainerView but we can only link one view in the storyboard.
I want to able to do something like this :
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! SearchQuestionBox
cell.questionAnswersZone.view = storyboard.viewNumberOne //Just for the idea haha
return cell
}
I would suggest not using multiple view controllers.
Instead you could just add the views for each cell to the one main view controller. Keep in mind you can set a views frame to be offscreen.

Swift coding multiple tableviews- how to connect them up?

Hi I'm new to coding so basically i've created a tableview app on github
the first one shows what i want to do without code https://github.com/edlen/guideline.git
and the second one is an attempt to recreate it with code
https://github.com/edlen/guidelines-via-code.git
but I'm really stuck about how to create code for going between screens so say for example on the main menu I select helpful info, how do i make the tableview with those options appear? and then if i select PO switch how do I segue to it?
Technically I can do what I want grand without code but I would really like to be able to understand coding of tableviews better and how to go between multiple tableviews and then select a final individualised view controller full of text.
Any advice that you could offer would be great- but please be prepared to speak very slowly and clearly as I'm still learning as i go along!!
At first, designing the app with Interface Builder inside Xcode is both the same for Swift and Objective C.
A UITableViewController should be embedded inside a UINavigationController, if you want to switch between views. Just drag'n'drop a UINavigationController and a UITableViewController into your storyboard - make sure the UITableViewController is the root viewcontroller of the navigation controller (right-click drag the tableview controller on the navigation controller).
After that, create a new Cocoa Touch Class - file (or press CMD-N). Look at this:
Make sure you choose UITableViewController at "Subclass of".
After that, go back to your interface builder and select your UITableViewController. There go to the identity inspector to change the class of your tableview controller. Look here:
After that, you just need to choose a reuse identifier for you tableview cells. You need the reuse identifier, so that your iPhone (or iPad) can reuse a cell and doesn't have to create a new one everytime. I just chose "myCell" as reuse identifier. To do that, click on the cell and go to the attributes inspector:
OK, the part with interface builder is done. Now go to your previously created MyTableViewController.swift.
There you have some methods. You need at least these to methods:
func numberOfSectionsInTableView(tableView: UITableView) -> Int
and
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
You need these methods, because the data source of your tableview is set to self. That means, this class is used to fill your tableview with information.
Let's start simple. To test everything, just use 1 section. So in your numberOfSectionsInTableView return 1.
If you have some data to be displayed, I think you'll store this data inside an array? However, in numberOfRowsInSection you have to return the number of rows that have to be displayed inside that section. So if you want to display 3 rows, just return 3 here. That makes 1 section with 3 rows inside that section.
Now you have to customize your tableview cell with labels and maybe an image view. So you need the function
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as UITableViewCell
// Configure the cell...
// add some UILabels or UIImageViews here.
return cell
}
to create your own cells. Here you'll need the reuse identifier you've set in interface builder.
A UITableView also has a delegate, which is responsible for events like (de)selecting a cell. So if you want to show a UIViewController when the user taps on a cell, you have to implement the method
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
Here you can switch between views. Here you need to have the tableview controller embedded inside a navigation controller (except you are presenting your views as modal view controllers, but that's not the point here).
So the user taps on a cell, you have the index of the cell inside indexPath.row - you'll need that to show the user the information inside the new view. After that, create your UIViewController or whatever, and present the viewcontroller with
self.navigationController?.presentViewController(myViewControllerToPresent, animated: true, completion: { () -> Void in
// some code to do after the presentatioin is ready
})
That's it!

How do you create a custom prototype cell with master detail view in Xcode?

I created an xcode project with the master detail template. I want to customize the cell to put my data into 2 separate labels. I tried customizing the cell in the storyboard editor, but it seems like all of the stuff on the cell is locked in place. I am fine either creating the custom cell programmatically or in the storyboard editor. I know I could just set the text on the default textLabel to blank and then create the other labels programmatically, but that doesn't seem very need to just have a random empty textLabel in the middle of every cell. So I am wondering if there is a way to edit the cell in storyboard editor, delete the default textLabel, or resize and reposition the textLabel to where I need it to go.
Any help is greatly appreciated.
Thanks in advance.
That's standard practice. Just ignore the built in textLabel and be done with it. By default the label is blank anyway. It's set in code.
To access new labels and such, create a new custom class for the custom cell (File|New|File...|Objective-C Class in XCode), give it a name and for the subclass choose UITableViewCell. Finally, on the Identity Inspector for the custom cell in Interface Builder, choose that new class for the Custom Class.
Now, from the Assistant Editor in XCode, you can CTRL-drag new labels and such to the .h file of the new custom cell class to create IBOutlet properties.
Be sure to set the cell Identifier on the Attributes Inspector tab for the cell and reference that in your code, especially in cellForRowAtIndexPath.
Import the custom cell class's .h file in the view controller's .h file, then cast the cell to your custom cell class in cellForRowAtIndexPath to access the new properties or change the definition UITableViewCell *cell = to your new class like MyTableViewCell *cell =.
By default, the Style of the table cell is "Basic" in Master-Detail projects. Select the Table View Cell and open the Attributes Inspector. Change the Style from Basic to Custom.
Doing this removes the default label and allows you to add new controls.

Resources