I have multiple tableviews that have various static cells and everything is cool.
I would like to implement some functionality to a button that is in one of the cells in all of the tables, but I do not know where the header and implementation files for UITableViewController are located and or how to access them. Any ideas?
You can't directly manipulate UITableViewController. Besides, it is not a good idea to do it anyway. The best way to do it is subclassing it.
Command+N and create a new NSObject file
When prompted, name it whatever you like (e.g. MyTableViewController)
Click on MyTableViewController.h in left side pane, and change NSObject to UITableViewController.
Goto the XIB file or the Storyboard (whichever you are using) and change the class of your UITableViewController to MyTableViewController.
Give a number to the button's tag field (e.g. 1001).
Now, in your MyTableViewController.m class, get a hold of the cell (cellAtIndexPath:) and then get a hold of that button with tag ([cell.contentView viewWithTag:]).
Related
I am creating a UITableView which has multiple types of cells.So I creating multiple cell using xib and for each cell I have one .h file one .m file and one .xib file.All these cells has some common things like cell background color,property(UILabel,UIView) and actions(UIButton click).
So I am doing a set of common things again and again.So how can I create a super class of these cell so that I can come out of the problem.I should be linked the custom xib cell to my super class.
Edit 1.0 :-
Suppose I have created a Super Cell subclass of UITableViewCell having the all the common properties of those cells in its header file (SuperCell.h) and also implemented all the common actions in its implementation file (SuperCell.m).Then I Made all those .xib cell header file as a subclass of my SuperCell. Now how can linke these .xib files header property to the SuperCell header property which is same.
Edit 2.0 :-
Thanks #Fogmeister for pointing me out that it will be a big hierarchies and difficult to maintain.And If I want to add some new label in child cell then I am also not clear where should I add and how to linked with the super cell.
Let me clear my question explaining my project a little bit.
I am creating an social app like facebook which has Text post,single image post,double images post,multiple images post, poll,event,etc.
So for my social app landing page I have a UITableview controller and all these type of post is linked to one one cells.All these cell has some common things like Post ownername(UILabel),#handler (UILabel),profile pic ( ImageView) ,Post time (UILabel),like button (UIButton),comment button (UIbutton) etc.
I have done everything and it is working fine.I have written a lot of common code for setting up all these cell as there is not SuperCell of these cells.So I am trying to figure out a solution to make it little bit easier.
Thanks
Ah, I see your problem now. As a very first starting point I can think of two possible (maybe three) ways of approaching your issue.
(N.B. everything here is just me using the Facebook app as an example, your actual app may differ).
At the moment you have different cells StatusCell, PhotoCell, VideoCell, ShareCell, etc...
Each of these have various different elements... userNameLabel, userAvatarImage, timeLabel, likeButton, commentButton.
Then each has a "contentArea" that contains the status, photo, video, url, etc...
First solution - Component views
The first approach I was thinking is to keep your different cell types but then to create UIView subclasses to easily populate the areas. So instead of the cells having the different user labels and images etc... create a view called UserDetailsView.
This UserDetailsView will take a single property of a User object. It then uses this object to populate the different labels it contains such as userNameLabel, userAvatar etc...
Now you can just add this view to each different cell type.
You can also create components for the ShareView which might include likes, comments, etc...
Second solution - Generic cells
In addition to creating these different components for each different type of Cell you could actually use a single type of cell. (This would only work if the content is in roughly the same place for each).
So the additional part to create now are the different content views. This might be a StatusView, PhotoView, etc...
Now you can use one generic cell type that has a space for a content view. (Maybe placed inside a container view for positioning and constraints).
Third solution - React Native
What Facebook does for their timeline is to use the React Native framework that they have created for immutable view hierarchies. This is a more complex method as it requires reworking the way you build stuff but definitely one to keep in mind for the future.
https://facebook.github.io/react-native/
create your "parent cell":
#interface SuperCell : UITableViewCell
#end
#implementation SuperCell
// background logic and all the stuff that is equal for your child cells
#end
with it's .h and .m files.
then create your "child cells" (with their .h and .m files) and make them inherit from your "parent cell":
#interface SomeCustomCell : SuperCell
#end
#interface AnotherCustomCell : SuperCell
#end
and so on...
I decided today that using static tableViews would suit my app better than dynamic ones.
Each cell has a label, and a UITextField
I subclassed one of the static cells and then tried to create IBOutlets for the label and textField... only it wouldn't work. Zero IBOutlet functionality when it comes static cells apparently and their subclass
I can however drag in IBOutlets to the UITableViewController these cells are apart of
So, essentially I would have a UITableViewController with outlets for each cell, each cells textField, each cells label, and potentially any other properties I want to add to the cell
I didn't want that much annoying code so I tried using dynamics
I was able to create IBOutlets for each object the way you can normally expect
I again decided against dynamics UITableViewCells, and switched back to static...
ONLY the static cells now have IBOutlets connected to them (they didn't disappear or throw errors when i returned to static UITableView)
I can access the cells properties by using cell.textField which is a lot better than a billion IBOutlets for each object on the cell
My question is... Why can't I create IBOutlets on the subclass of Static TableViewCells
Is the way I did it the only way, or is there a better way? I would hate to keep switching back and forth, but it allows me to get rid of dozens of lines of code I'll do it
When you create IBOulet for a UITableViewCell and you try to connect them on your StoryBoard, go to the left bar (where the objects of your view controller are) and press Ctrl + Click over your custom cell. Then the IBOutlet object will appear in a popup and you will be able to link them.
As a small disclaimer, I'm pretty new to iOS Dev and have mainly worked with Appcelerator Titanium in the past, so this may be pretty basic.
Currently I'm in the middle of trying to create a page in an iPhone app that pulls data from an external API. That API returns a JSON array of objects that I'm using to populate a table (pretty standard behavior).
Each hash in the array contains of squares that I need to display in the table view and thy are formatted different based on the number of squares. For example:
If one comes back the table view cell contains a name and a single large square.
If two come back the table view cell contains a name two slightly smaller squares positioned overlapping.
If three come back the table view cell contains a name three slightly smaller squares positioned shaped like a triangle.
If four come back the table view cell contains a name four slightly smaller squares positioned in the shape of a square.
If more than for come back the table view cell contains a name, four slightly smaller squares and the last square has a +x count for how many there are in addition to the first 3.
Note: The name is in the exact same place on each cell.
So the real question is it seems like I'm not sure which of these two options are the best way to go:
Create 5 different SpecificCell.xib files (along with .h and .m files) and in cellForRowAtIndexPath create one of those and return it. This seems like a LOT of duplicate code for name, etc. and in general just a ton of code (15 new files) for something that realistically only changes a part of the cell (Name remains in the exact same spot, only the square images change).
Create a single Cell.xib (along with .h and .m files) and pass the dict to a new function that returns a parent view and the child square views, then add those to the cell in cellForRowAtIndexPath.
My main concern, and I'm curious what actual Objective-C developers tell me here haha, is do I receive memory benefits from using the first approach because the app already knows in memory how to create a cell with those exact views?
Or, is there a third way I don't know yet?
Your analysis of the issue is correct, and if this is as small as you describe there shouldn't be a performance penalty either way. Both of these are correct, but you have more options:
Create a class for each cell (and new xib), but combine them in one file. It's only by convention and Xcode's "new file" windows that each class always gets its own file. TableViewCells.h (TableViewCells.m is optional if you're just adding IB outlets). Then in this file:
#interface OneImageCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *firstImage;
#end
#interface TwoImageCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *firstImage;
#property (weak, nonatomic) IBOutlet UIImageView *secondImage;
#end
Easy to forget this creates the class, not the file in the list. Probably not necessary in this case, but good to know if you do find yourself needing many tiny subclasses and don't want to clutter the file list. Swift actually does away with the convention of one class means two files, good riddance.
Create new .xibs for each cell, but one combined class file and switch dynamically. Long the trick for combined code used iPhone/iPad apps, I find it it's a bit cumbersome to set up and manage. Useful if you're creating prototype cells in a tableView in IB, since you don't have to write the code, just set the class of the cells to be the same and reuseIdentifiers to be different.
Use the same xib .h and .m, but use different reuse identifiers. The reuse identifier fulfills its purpose here. Regardless of the same class and xib, if using different reuse identifiers then they will go into the same pool, saving setup work when reused. In -cellForRowAtIndexPath setup and use the kind of cell you need, and you could set a flag as a property of the cell to confirm setup work has already been done, saving that work.
Of these, 2 with IB is probably the simplest and most Apple-y, which is usually the way to go. All would be fine, including your two -- save work when you can, but again, even doing light-to-moderate setup in -cellForRowAtIndexPath is usually fine.
I'm learning about xib files and just starting to understand why people use them as well as or instead of storyboards. My question is about how and when it's appropriate to use the xib as a "template".
Let's say I have a xib mapped to my custom UIView subclass - I know how to set that up in IB - and my xib has a UILabel subview. This is a very simplified example just for the purposes of the question, but basically I'm trying to create a view that can be reused for each screen of an iOS "introduction" walkthru, like the panels of https://github.com/MatthewYork/MYBlurIntroductionView
So I want to set most of what's in the view up at design time, and most of it will be common to each instance. The text I want to put in the UILabel is going to be static (i.e. I know it now at design-time) but each instance of the view will have different text. So let's say that I want to position the UILabel in different places in each instance, depending on how much text is in it etc and whether it's covering something else important. Now, I know I could do this programmatically, i.e. have the label as a #property linked up in IB and then set frame position in the code, but as far as I understand it the beauty of using xibs is that you can do known things like this at design-time.
As far as I can see my options are:
Load new instances of the xib and set the position etc programmatically as mentioned above (would rather not if possible)
Create my template xib, setting all the common stuff, and then make copies of it "CustomView1.xib", "CustomView2.xib", etc. (a bit yuck but not too bad)
After creating my template xib, use the storyboard to drag in new UIViews and somehow set each to be linked to my one "CustomView.xib", and then somehow do my static repositioning of the subview UILabel within each of those UIView instances on the storyboard. Is that possible? If so that'd be great. Obviously I know I can set each of those UIViews to be instances of my UIView subclass, but I'm just missing the link between doing that and customising each instance. Does the file's owner have something to do with it?
So I guess the table view has been designed around the idea of using dynamic data received at run time, but I want to make a settings type app where all of the cell values are known as I build it, so I was hoping to be able to set the section / row configuration, labels ect, as well as the properties for each cell (whether it has other views inside it like a switch, or whether it is a button etc) all in interface builder.
can I do that? how?
I am using xcode 4.4.1
To use static cell content you have to make sure that you are adding a UITableViewController not just a UITableView dragged into a UIViewController. The latter requires dynamic prototypes.
Once you've added the table view controller to your storyboard it is as simple as selecting "static cells" in the attributes inspector. From there you can drag and drop UITableViewCells and modify them as you wish.