How can I use an UIScrollView in an Multiview-Application? - iphone

I have:
- an AppDelegate class
- two viewController classes
- three nib files (MainWindow.xib, firstView.xib, secondView.xib)
I want:
The secondView.xib should have an UIScrollView inside, so that I can add a lot of stuff to the view and it can be scrolled down.
Where would I have to conform to the UIScrollViewDelegate protocol now? I feel the AppDelegate class is the wrong place, because its far away from that secondView and not all my views want to use a UIScrollView.

since UIScrollView is located in the secondView.xib I assume its functionality is limited to that view. If you have an instance of UIViewController that serves as the controller for the secondView.xib then the best place to implement UIScrollViewDelegate would be on that UIViewController directly. You are correct that implementing it on the AppDelegate doesn't make sense if you have a more specific derived controller where it should belong. Hope this helps!

Related

Creating a base class for customizing the view and let other (UIViews) inherit from that class

I read this post but I can't get it working: Change Background Color...
I like to create a base UIView class for all my view customization like background pattern, color of the buttons, color of the tab bar etc.
This is what I've tried:
Created a new Single View Application
Customized the view in UIViewController method -viewDidLoad
Created a new subclass of that UIViewController
In IB I created a new UIViewController object
In IB (Identity Insp.) I set the UIViewController class to the subclass I created earlier
Is this not the proper way to do this?
I was thinking that the new created UIViewController class will inherit all
customizations from my first UIViewController class since I subclassed that one.
Second question is how can I use a base class for certain objects instead of a whole view?
For example how do I let all UIButtons in my App inherit all the behavior I have defined in just one single class?
Hope you can help.
Happy Easter for all.
I believe you want to customize your view, but exactly how and when is not clear to me.. so I will just give the common method which will give you the general idea of how to do it..
First create a subclass of UIView say BaseView with properties to be customized, now in the viewDidLoad methods of your viewController create an object of BaseView and customize this object as you like.. once this is done just set the self.view property of your viewController to this newly created BaseView object and then release the BaseView object..
hoping this helps you somewhat...
EDIT:
based on the comments ..
First create a BaseViewController class which subclasses UIViewController... in the viewDidLoad of this class customize your view using self.view
Second now the viewControllers which you want to use in your tabController should subclass this BaseViewController... just don't forget the [super viewDidLoad]; is called in the viewDidLoad of this viewcontroller.
this is the best I have to offer.. :) let me know if it works for you.

How to get access to UITableViewController properties when subclassing from UIViewController?

I have subclassed UIViewController to provide common functionality for all UIViewControllers (for example I'm overriding viewDidLoad method). My app uses a bunch of view controllers that are arranged inside tab bar controller and in navigation controllers. Everything is OK, except the fact I have one UITableViewController. I would like to subclass not it but my custom MyUIViewController. I'm able to get the table working by implementing data source and delegate protocols:
#interface MaschinenTableViewController : MyUIViewController <UITableViewDataSource, UITableViewDelegate>
However in this case, I do not have an access to UITableViewController properties. For example, I cannot change the behavior of table row selection because self is MyUIViewController not UITableViewController:
self.clearsSelectionOnViewWillAppear = YES;
Are there any workarounds for accessing those properties?
In this case you will need to add a UITableView variable to the header and set it up appropriately in viewDidLoad, and add it to your view. From this point it will work as a UITableViewController will (as essentially that's all it does!)
Take a look at my article here which takes this approach.
You could also subclass UITableViewController as MyUITableViewController, implementing the behavior you want, and then put a MyUITableViewController as variable to your MyUIViewController.
Did the same as Simon Lee mentioned using the delegate.
But without storing the index anywhere, at the end of didSelectRowAtIndexPath method called the deselectRowAtIndexPath. Worked for me no issues so far.

Does UITableViewController allow the table to be in a UIView?

UITableViewController seems to always hijack the View link in IB. So, if I put UITableView in a UIView and link up the View to that UIView, it still doesn't work. Only the UITableView is shown.
What I'd like to do is use a UITableViewController and put some labels on top of the uiTableView that can be hidden.. Like loading.. and No results found.
The only solution I have come up with is to resort to using UIViewController and then adding a UITableView link to the class and link it up in IB.
Am I missing something here?
It's fine to use a UIViewController, make it implement the table view datasource and delegate protocols, and then hook a UITableView up to it. It's also fine to have the controller's main view be a container UIView, and have a UITableView as a subview of that.
And yes, this is probably the best way to add some kind of overlay view, such as a message label. So I think you're on the right track.
You should also be able to do this using a UITableViewController, instead of a UIViewController that explicitly implements the table view protocols. I've had success with this. I'm not sure what you mean when you say that UITableViewController "hijacks" the view outlet in IB.
It really isn't a big deal either way. UITableViewController doesn't do much other than implement those protocols, provide a different default loadView method, and call [tableView reloadData] by default on viewWillAppear:. If you do those things yourself, you'll be fine.

Create a UIView Subclass that calls a delegate function whenever it's parent viewController appears?

EDIT 2: I now think the best soluton is to create ListeningView.h that just includes a ListeningView protocol, instead of subclassing ListeningView (since we can't do multiple inheritance in Obj-C). Then, you still need ListeningViewController as well.
EDIT: Ok, I figured out what the approved idiom is here. I should subclass UIViewController to create ResponderViewController, which will loop through its subviews for ResponderViews when it appears/disappears. Then, any viewController that has responderViews should inherit from ResponderViewController.
=======
UIViewControllers have viewWillAppear, viewDidDisappear, etc. delegate methods.
I would like to create a UIView subclass that can be added to a viewController's view, and when that UIViewController apears or disappears, a delegate function is called.
I could easily do this by putting function calls in the UIViewController viewWillAppear/viewWillDisappear delegate functions, but how can I encapsulate this behavior in the UIView?
I wouldn't do that if I were you. All that sort of behavior should not be controlled by a view; that's just was controllers are for.

MVC: Where to load views?

I have a relatively simple app. I have a fullscreen UIView subclass (musicGridView) that the user interacts with, and a UIScrollView subclass (scrollView) that loads this class in, as well as a ViewController and mainWindow.xib.
Right now, I have a viewController instance loaded in the nib, which is of type myViewController. The nib also has instance of myUIView, which the myViewController is pointed to.
In AppDelegate, I do this:
[window addSubview:scrollView];
[scrollView addSubview: viewController.view];
scrollView.musicGridView = (MusicGridView*) viewController.view;
which I think is wrong. Ideally, the appDelegate doesn't have an instance of scrollView.
In scrollView's AwakeFromNib class, I do the initialization on the scrollView.
The way I think it should go, is load the [window addSubview:viewController.view] in appDelegate, and then point the viewController to an instance of scrollView instead of musicGridView. Then, in scrollView awakeFromNib add a subview of musicGridView.
Eventually, I want to create another view owned by scrollView that is actually a side TabBar (which isn't possible with the given API's) that the user can scroll to the left to reach.
So I guess amongst other MVC stuff, the question is, should the viewController point to the scrollView, which contains all other content UIView subclasses, including musicGridView?
It sounds like you are not using Interface Builder to design your UI. Since this is a new project, I would suggest doing that. You should not have to write any code like this at all. You will however need to describe your outlets and actions.
The two most important things you need to know when dealing with IB are the IBOutlet and IBAction keywords.
Sample class header:
#interface MyClass : NSObject {
IBOutlet UIScrollView* myScrollView;
}
- (IBAction) doWork;
#end
Now you can wire these two things up using Interface Builder by dragging sources to destinations with your mouse. YouTube has lots of tutorial videos on IB if you need a better description of how to do this.
I'm someone who doesn't use Interface Builder for UI design; in my experience, you need to go either all-IB, or all-programmatic. To solve your particular problem, I think you need your musicGridView to be an instance or extension of UIScrollView.
This can be done in your custom viewController's loadView method - simply initialize it to a UIScrollView (and add things to it), instead of a plain old UIView.
However, as described above, this approach isn't compatible with an IB-centric approach, as is confirmed in the UIViewController Class Reference
All subclasses of UIViewController
should implement the loadView method
to set the view property unless you
load your view from a nib file.