How can I reuse a View object? - ios

I have that view object with some elements. I want to call that view , and can use it in another view, having a list of objects view one below the other. The problem, I do not know how I can create like a component.
Regards

Create a subclass of UIView, and do what you need to in the view, and every time you want to use this kind view, just use an instance of this class.

I think you want to use a reusable UIView, so in your case I think you will create a xib in Xcode.
Regards, Jorge.

Have a look to Container view in interface builder

Related

Moving UITableView in xib

I have a simple question for you.
I load images and strings from sqlite3 base. If there is no image, i want to move up my table view.
How can I realize it? I tried to change frame.origin.x, but it doesn't work.
Link to my project https://github.com/serg1991/diplom
Can you be more specific about the exact position of your problem in your project? It's kinda big.
Also, if you need to move up your view, what you want to modify is frame.origin.y.
Otherwise, make sure you don't change your tableView's frame too early in the view lifecycle. Try doing that in the -viewDidLoad of your controller.
Be sure not to use a TableViewController in storyboard... Use a viewController, and drag a tableview inside (of course now you'll have to manage the delegates your self).
Hop this can help

How could I clone/duplicate some sort of UIView for iOS?

(screenshot below helps explain what I am trying to do)
The idea behind this is that I have a UIView, with various different UI elements inside, for example, let's say I have a UIView, and inside there we have a UILabel.
Now I'm wanting to duplicate the UIView (with the label inside) BUT somehow after that I need to perhaps make a change to the label, e.g. change the text property.
The reason I need something like this is so I can structure the UIView with everything I need in it looking nice, but to actually have different data with different copies of it.
I'm not certain this is the best approach, but it's the only one I could come up with. If anyone has any ideas on how to do this, or any ideas on a better approach I'd really appreciate it. A lot!
I personally think the best answer is to create each view separately and configure it as needed. You can make a method that just configures new UIViews to look the same, and pass each view through it.
However, if you really need to copy a UIView, you can archive it, and then unarchive it:
id copyOfView =
[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:originalView]];
UIView *myView = (UIView *)copyOfView;
[self.view addSubview:myView];
If you have a bunch of these, make sure you're using the Instruments time profiler to check your drawing efficiency.
This is a very natural and useful thing to do. What you're looking for is a container view controller. Put your reusable "cell" into its own view controller and its own nib file. Then, in your parent view controller, use addChildViewController: to add as many of these as you'd like and configure each of them. They can each have their own IBOutlets that you can use to modify the contents.
This is very similar to the pattern used by UITableView and UITableViewCell (it doesn't use "child view controllers" specifically, but it does use this pattern).
For full details, see "Creating Custom Container View Controllers" in the View Controller Programming Guide for iOS.
Note that Storyboard includes a "Container View" as an option in the object templates to make this even easier.
If you want lower-level access, you can also do this by hand using UINib to load the nib file and wire its outlets (and this is how we used to do it before iOS 5), but today I would use child view controllers.
If you have only one label inside it the obvious solution is to have a custom UIView subclass with that label added as a subview. Everytime you need a new view you make an instance of your custom subclass and set the label text. If you have multiple things to set, some of which are common to all your custom subclass views you can use the prototype design pattern, it's pretty straight forward to implement.

How to add multiple instances of custom subviews in UIViewController

Often, when I'm making my apps, I'm in this situation : I have a UINavigationController, handling the view stack, some UIViewControllers, controlling their respective views...
But when I want to add several custom UIViews in my mainView, I don't know how to manage my code.
Each UIViewController needs to handle one and only one view (wich normally occupy all the screen size), and a view should not control their content (update it a the extrême limit).
You can't neither do this :
[myViewController1.view addSubview:childViewController.view];
So if I want to achieve something like this, what should I do ?
The orange parts have to be 3 instances of the same UIView(Controller?), but with a content depending of a NSObject (User, obviously).
I think this very important to segment your content, this should be an easy problem, but I found a lot of contradictory answers so, what's the best practice to handle this common issue?
Theses orange views should be instances of UIViewControllers in order for it to handle their UITableViewDatasource? Is addChildViewController relevant in this case?
I already found a lot of things which work, but I don't know what should I do...
Also, I'm using xibs.
Thanks in advance if you can help me (and other people I think).
You can do it either way (view or view controller) depending on how you want to handle things. Certainly, you can have one object be the data source for multiple tables, so in that case, you would just add multiple views. If, however, you want to keep your code more compartmentalized, then add view controllers, and have each control its own view -- to do this, you do need to use addChildViewController, and use the methods that Apple describes for creating custom container controllers. Alternatively, you can use container views in a storyboard which makes the process of creating custom container controllers simpler.
You're on the right path... Create separate instances of your subviews, and add them to your view. If you will have more than 3 (for instance, imagine coverview for your music, and you could scroll indefinitely left and right), I'd take a look at UICollectionViewController ... That will help manage cell re-use.
But, if it's just 3, just create three instances with different frames and add them to your view.
Here's how I'd do it:
each orange box will be a custom view (inherits from UIView)
the view will have the label, image and the tableview.
since you are not sure of the number of instances of these views you'd be using, its better to use some kind of tagging, so that you can have one place for the datasource and delegate methods of the tables in these orange views.
in the datasource and the delegate methods, you can make use of the tableView.tag (same as the orangeView.tag property).
I personally dislike having more than one viewController in a view (except the splitVC), probably because I haven't had a such requirement.
I dont see how a uiviewcontroller for orange box would help, over a uiview.
as #James Boutcher mentioned in his answer, UICollectionViews will simplify this issue further.
Why not creating a UIView class and overriding the drawRect method and then adding subView for this class in your myViewController1.view

QuickDialog within frame

I'm trying to employ QuickDialog for an iOS 5 iPad app which uses storyboards, but I guess the question would broadly apply to UITableViewController as well.
My understanding is that when I'm initialising the QRootElement, the tableview that QDC creates will replace the view of my class, thus rendering ineffective anything I customise in the IB storyboard. I would like to be able to design the UI in IB, and have the QD table show up as a frame instead of taking over the whole screen.
I think the solution is to have the QuickDialog tableview set up as a subview of my UIView-based class. Is this correct? What would be the best way to achieve this? Would I have to rewrite the root initialiser in my custom view controller that inherits from QDC, or is there a different way, perhaps something like the approach used here?
Thanks!
I would recommend you inherit from the QuickDialogViewController as your main controller. The QDViewController inherits directly from UIViewController (instead of UITableViewController), so it's quite easy to just move the table view around and add controls around it.
If you really want to create everything from Interface Builder, your tableview will have to inherit from QuickdialogTableView, and you'll have to provide the delegate and data source yourself. Look at the QDViewController for that, as you'll have to write pretty much the same code.

Connecting a UIView to a UIViewController

I have a UIView subclass which contains some labels, a tableview, and a few other bits an pieces. It is currently the delegate and datasource for the tableview, and also manages many UI actions, none of which rely on data. For example, when an 'edit' button is pressed, it knows how to update its controls, but it won't do anything when 'save' is pressed besides switch the controls back to the previous state. All of this is done in code, I'm not using IB at all in this application.
I now want to plumb in all the data model changes that it can provoke. But I would like to put these in a new controller class, which I guess is the MVC compliant way to do things. I'm not sure how to get there.
First, I need to create a custom controller class. Should I be exposing from the UIView subclass a few of the controls so that the view controller can access them? For example, I will need to read and write to a textfield in the view, so should I provide a getter/setter for this?
Secondly, the tableview - instead of the UIView being the delegate, should I expose this also, and make the view controller the delegate? I.e. view.tableView.delegate = self from the UIViewController?
And finally, how do I launch the view from another view? Specifically, this is a paged scrollview application similar to the weather app, so I have a mainView UIView that specifies the single paged scrollview and then adds multiple custom UIViews, one for each page. How do I replace [scrollView addSubview:myCustomView] and instead add the viewController? And how do I connect the view to it's controller and vice versa?
I've not tried all of this without IB before so thanks for helping.
Your question is very broad, and part of the answer would depend on how you code your solution. I will try replying with a few hints of what works for me:
View: As a general rule of thumb, keep in mind that a view object should be something very generic, that knows nothing about other views outside of its own hierarchy. As such, a view should not rely on any specific interaction with other views, but rather communicate back to its delegate / owner / creator through callbacks, protocols, blocks, etc, when needed.
View Controller: Any time you need to make two views in different hierarchies interact with one another, my suggestion is that you stick to handling that interaction through the view controller. By doing so, you'd be making sure your view is not contaminated by code that would be useless in a different screen.
Also please keep in mind that UIViewController for iOS is intended to be a class that you use for handling the complete visible view hierarchy, as opposed to acting as the controller for a single view. As such, I recommend that you don't attempt have a controller for each view, but rather a single one to handle them all.
Publishing view elements: How much a UIView exposes as public in its header file is up to your implementation. Any method that handles the way the view looks, that looks to be generic and reusable, and that doesn't need anything from outside the scope of the view's tree, is surely something you want to include in it's implementation and publish in the header file.
The same goes for any property that you feel is highly probable that someone from the outside will need to access.
Suggestion: publish only what's really needed. Usually publishing new methods and properties is easier than removing them later on.

Resources