So I know that you could reference a UITextField that you created in the interface builder by creating a custom UITableViewCell class and connect it with an IBOutlet.
But is this good code practice? I mean I am basically just creating a new class for a UITextField. Is there a more suitable way to do this? AFAIK you can't set an IBOutlet to the UITableViewController itself since you can't reference objects on repeating content.
Yes this is a good practise. When I first started learning swift, I myself went through this phase because creating a new class overtime seemed a lot of work. But trust me, it is the best way. I learned swift from a book which I bought from AppCoda. It always emphasises on creating custom classes for tableView cells as well as CollectionView cells.
In your example you have 2 prototype cells, creating custom classes for both of them helps in differencing one cel from the other. Also, you will also not get confused between the two. This also helps in changing settings/appearance of cells as you like and with ease.
Hope this helps. :)
Related
I have a lot of common logic, therefore all my viewControllers inherit from BaseViewController, BaseDetailsViewController or BaseWebViewController. The last two inherit from BaseViewController which inherits from UIViewController. The problem is I cannot use tableViews with static cells because my BaseDetailsViewController is not inheriting from UITableViewController.
I'v never used and inherited UITableViewController because the same could be achieved by inheriting from UIViewController, wiring it with an added UITableView and having implemented datasource and delegate methods. Therefore for the form type screens (SignUp or other data input screens), I use my own BaseDetailsViewController which adds nice and handy methods (input validation, custom styling, scrolling keyboard, handles input field navigation and etc.)
Using UITableViewController has two real benefits: 1) keyboard scrolling (if you use text fields) and 2) easy creation of your form UI elements inside on screen. The first benefit is irrelevant for me, because I'v already have my own implementation of this stuff inside BaseDetailsViewController. Regarding the second benefit, I'm creating my form inside scrollView which gives a lot of flexibility but it's a little bit more effort (especially when need to update the screen). Therefore I heard some guys implemented their own UITableViewController and then made it to inherit from their BaseViewController. Therefore I started to dig into this approach.
So far I'v came upon these two approaches:
Recreate your own tableVC. Not clear how to make it work for static cells. Currently my demo app crashes if my ReplaceTableViewController is not implementing numberOfRows and cellForRow, and not shows static cells if I implement them with dummy content.
method-swizzling. Not clear how to change class inheritance by injecting baseViewController inheritance for UITableViewController, thought still not clear which methods are needed to be added.
Anybody tried and want to share?
UPDATE I'm not using storyboards as I promote clean MVC - every screen as component should have its own Model, View (Xib), and controller, all stored in separate files to eliminate merge conflicts of multiple devs in large app projects (30+ screens). And therefore container view with embedded segue to tableViewController is also not an option.
UPDATE2 In case anybody would like to take a look why and how I'm doing this, here's a link to my open source template based new project generator framework which I started to publish recently.
Static cells need a UITableViewController. You can't changed this right now.
But to use static cells in a UITableView outside of a UITableViewController you can use a ContainerView in your Non-Table-UIViewController, where you place a real, separate created UITableViewController working with those static cells.
To share common code between multiple view controllers, inheritance is not that best solution as you found out by yourself while subclassing UIViewController vs. UITableViewController. You can use some sort of composition for sharing code or - especially for objective-c - categories.
Categories are not allowed to have its own properties, but there are workarounds possible with objc_setAssociatedObject.
Another approach would be to not use static cells, but dynamic cells in a UITableView with DataSource-Delegate :)
As you see in my screenshot, to reuse a special TableView with static cells, i place it in other ViewControllers in a ContainerView. Since you are not using storyboards, i am pretty sure that this can also be done by code without storyboard.
Custom Cell For UITableViewCell
I'm developing an iOS application and i need to make a custom cell for my side menu, i have seen so many examples and i found out those two approaches :
Make a class (.h and .m files) that inherits from UITableViewCell and put the outlets in the .h file then apply the class on the cell and connect those outlets to the labels and/or images from your cell in the storyboard.
Or the easy way is to give a tag to the labels/images or whatever you have in the cell in your storyboard.
My Question: I'm wondering which way is more accurate and professional and used by most iOS developers ?
Definitely the first one. It's clear and maintainable in the future. The purpose of the tag is not to store arbitrary values. See my answer regarding this.
This article has some details on the usage of tags
What all does UITableViewController get me that makes it actually useful? Is there any bonus is using it instead of just using a UIViewController for views with UITableViews in them? I ask because I want my views with UITableViews to inherit from a base view controller (which inherits from UIViewController). If I use a UITableViewController then having a base class for all my views becomes more difficult.
Not much. It provides some conveniences, but you never really need it; I often don't use it.
The main things, aside from the automatic setup when you create one in the storyboard, are the three properties tableView, clearsSelectionOnViewWillAppear, and refreshControl. But they don't do anything you can't do yourself.
Well I do think both Retro and matt's answer are correct, from personal experience it is much easier and less "hackY" to use UITableViewController with UIRefreshControl, then trying to get UIRefreshControl work with UIViewController with a UITableView.
Nothing more then the boilerplate code ready for setting the data source and connection to your tableView object, some getters and setter to make your life easy if you not want to put your effort to do the same thing which is available.
But in your case for SubClass its not fit to have UItableViewController
Can i have two images and a few text labels in a cell of a tableView ? All dynamically assigned ?
Yes, read the documentation for the UITableViewCell class, specifically the UITableViewCellStyle constants which allow for various types of standard table cells to be created. If the built in styles do not meet your requirements, you can subclass UITableViewCell and create anything you want, since it's just another type of UIView.
Of course you can! There are several ways of achieving that, the most popular being subclass the UITableViewCell class, and creating your own custom cell, and you can have whatever you want in it. But just to get an idea of how to go about doing that, I suggest you go through the following links:
Table View Programming Guide for iOS - Apple
Crafting Custom
UITableViewCells - MobileTuts+
I am trying to build a custom UIPickerView replacement class mainly for learning purposes but with a view to implementing this within an application I am developing. I have put a lot of time and effort into the UI of my application and now the default UIPickerView just doesn't fit right.
I saw this Dribble mock up of a really slick looking date/time picker but realise that theres not a chance in hell that UIPickerView can be customised this heavily without some major hacking.
After a whole lot of reading and investigation, I have found that UIPickerView uses UITableViews for it's components rather than a plain UIScrollView as I had first assumed. This is confusing for two reasons:
Customising UITableViewCells is a major pain in the derriere. It's not that it's hard work, just laborious and rarely yields the required result. Somehow UIPickerView manages to pull this off though with very little overhead. I would assume that each row in a component just uses UITableViewCellStyleDefault with a custom view for it's contentView but you know what they say about assumptions.
The second thing that is throwing me off is that UIPickerView conforms to the UITableViewDataSource protocol, but not the UITableViewDelegate protocol. This seems a little odd as the delegate is responsible for providing the correct height via – tableView:heightForRowAtIndexPath: UIPickerView however does allow you to set the size of a component via – pickerView:rowHeightForComponent:
In line with this, it also seems a strange choice to utilise a table view as natively these do not "snap" to a specified row the way a scroll view would with pagingEnabled.
Can anyone offer up an explanation of why the default UIPickerView doesn't conform to the aforementioned delegate? Would it be easier for me to implement my custom picker with a UIScrollView instead or should the UITableView provide the functionality required?
UIPickerView actually conforms to UITableViewDelegate protocol but just does not expose that in public headers. You can check that yourself using class_copyProtocolList function.
Using UITableView internally makes it much easier to implement pickers with large amount of rows as UITableView provides great support for reusing cells, otherwise Apple would need to reimplement that logic once again for picker - that would not make much sense (sorry I don't see any big problems in customizing UITableViewCell for this case, so it is hard to comment on that)
As UITableView is UIScrollView subclass you can make it "snap" to a specific position, check scrollViewWillEndDragging:withVelocity:targetContentOffset: method in UIScrollViewDelegate protocol that can be used for exactly that purpose.
Custom UIPickerView are done by mimicking it's behavior using an UIViewController subclass containing as many UITableView you need for fields.
Eg: if you want a time picker, use 2 tableviews
You should style them in a xib using images and such.
What's -kinda- hard about reproducing the behavior is the part where UIPickerView "snaps" to the closest cell, and especially getting it right.
Also, cells in a UIPickerView are simple, just no borders/delimiters between cells, text label is centered, and voilà. What you see are just images overlaid in front of the UITableViews.
As to why it doesn't fully conform to the UITableViewDelegate, it's because in fact, it's a lightweight UITableView that snaps automatically that is used internally in UIPickerView. Thus, it lacks some delegates that are not specially useful for this.
But I guess we all agree on one thing: Indeed, building custom UIPickerView is a big pain and should be easier.
Take a look at this component, looks quite nice, though I haven't tested it myself. computerlogicx/AFPickerView
I managed to implement an "alternative" UIPicker by extending UICollectionView.
Although UICollectionView is usually used for cases where you have multiple items in a section, you can just have one item and it works fine. If you enable paging you get similar behaviour to a UIPicker, but it has a "stickier" scroll that only lets you scroll one item at a time, which might be better if that is what you want. Furthermore, you can scroll vertically or horizontally. You could even have a 2D picker with some extra code.