I created this screen-cast yesterday to help out those who have been wondering how to use multiple XIB files in their projects. The link is below, and don't hesitate to let me know what you think. The video was recorded in 720p and was converted into MP4. You should be able to view it full screen without too much distortion.
Chris asked me to come back and embed the videos in these pages. But I didn't realize until I did it that the embedded versions weren't HiDef. However, you can click the link below the video to be taken to vimeo.com and you can view it in HiDef from there, or you can click the download link and download a HiDef version to your computer. All the videos except for this one are 75-ish meg in size.
I think the implementation you showed in the video may not be the best example of good MVC (Model-View-Controller) design pattern practice. I am no pro either, but I dont think you should be accessing the application delegate from a UIView subclass, this sort of thing should probably handled by a controller object, such as your UIViewController subclasses. then they need to be hooked up in IB accordingly.
Thanks for the tutorial, I did learn a lot and I appreciate it.
I see your point, but I don't see how you can get around having a lot of extra fluff in your programs if you make your UIViews access their view controllers to access data that the view controllers get from the delegate. The "proper" implementation also makes for more work. I'm a big believer in the idea that the easier you make something, the better.
Then again, I always got counted off on my programming assignments when I was in college because I wouldn't do things the way they were "supposed" to be done. I had several assignments where I lost points for not following the assignment, only to have them added back on for thinking outside the box....not that this is the same type of situation, but the code works and is rather minimal. In the end, do it however you're comfortable.
Thanks for the compliments and constructive criticism.
I really liked how you used the delegate in this tutorial, thanks for this. Like others I would have probably used the view controller for most of the stuff, but I think whenever I have the opportunity I will use the delegate now.
@aoberoi: Not to be a stick in the mud over your comments, but I went back and looked over Apple's example code for table views and their samples store the content array in the delegate and access them the same way that I do it in the tutorial. In the end, it all comes down to being able to access your content from anywhere in your program. If you store it in a view controller instead of the delegate, then you're still going to have to access across classes regardless of your implementation. Therefore, the delegate makes the most sense.
Oh I agree completely that the application delegate is implemented correctly.
My difference of opinion (and thats all it is) is where the methods such as sayHi and tellDelegateToFlipView should be implemented. I think there should be outlets for these methods in View Controller classes. These classes typically implement the functionality of items placed in the Views. To communicate with data used by the whole application, yes it makes sense to go to the app delegate.
In this small example, an easy to understand method does have its obvious advantage. I am only commenting that in order to use the principles of the design pattern, technically the functionality of those buttons should be moved to a view controller. Otherwise, one might ask, why did I have to make a class file for the view controllers? I never used them right? Also, if it was implemented the way I suggested, there would be no need to make source files for either of the Views, and less source files to me means easier to understand.
I've just seen the video and I think it is great! I really like the way you coment your code and how you thought on doing the presentation in general. I'm just a beginer, but I feel I understand most of what you said.
Having said that, one thing I still don't quite understand is the MVC design pattern, and reading on your comments here, I feel quite lost. At the moment I'm just doing things so I get the apps working, but I keep feeling I'm not doing things correctly. The problem with this is when I come back in a few months, maybe it will be hard to read my code (not that I'm really going to do that, I hope I know much more than now). The point is that I think the understanding of the MVC is important for readability and reuse, specially if working with other people.
All of this is to say that if one day you feel bored, could you make a video on MVC ? Well, either that or could you point me were to read to better understand it all?
Oh I agree completely that the application delegate is implemented correctly.
My difference of opinion (and thats all it is) is where the methods such as sayHi and tellDelegateToFlipView should be implemented. I think there should be outlets for these methods in View Controller classes. These classes are typically implement the functionality of items placed in the Views. To communicate with data used by the whole application, yes it makes sense to go to the app delegate.
In this small example, an easy to understand method does have its obvious advantage. I am only commenting that in order to use the principles of the design pattern, technically the functionality of those buttons should be moved to a view controller. Otherwise, one might ask, why did I have to make a class file for the view controllers? I never used them right? Also, if it was implemented the way I suggested, there would be no need to make source files for either of the Views, and less source files to me means easier to understand.
I have to agree with aoberoi .. the delegate was used correctly just that when you link a view to data you are making it less reusable. Apple states controllers should be the non reusable part of your program so you should separate a view from a views data, doing so will in turn (hopefully) make your view classes and model classes reusable.
Quote:
Originally Posted by aoberoi
Oh I agree completely that the application delegate is implemented correctly.
My difference of opinion (and thats all it is) is where the methods such as sayHi and tellDelegateToFlipView should be implemented. I think there should be outlets for these methods in View Controller classes. These classes are typically implement the functionality of items placed in the Views. To communicate with data used by the whole application, yes it makes sense to go to the app delegate.
In this small example, an easy to understand method does have its obvious advantage. I am only commenting that in order to use the principles of the design pattern, technically the functionality of those buttons should be moved to a view controller. Otherwise, one might ask, why did I have to make a class file for the view controllers? I never used them right? Also, if it was implemented the way I suggested, there would be no need to make source files for either of the Views, and less source files to me means easier to understand.
Message disclaimer: I don't pretend to know it all, and my advice probably isn't the best. Coding is one of my hobbies, and I've been doing it for around 15 years. I try to make my code easy for me to understand since I'm the one that maintains it and uses the final product. If you like your way better or think I'm full of crap, then that's your prerogative. I fully realize that all the message thus far in this thread have been constructive criticism, and I'm not angry or trying to be defensive about anything. I'm just posing my point of view and trying to help others that may be having trouble figuring out things that I know how to do.
I'm going to toss this out there just for the sake of asking....no other reason at all......
Has anyone here ever really reused a view for anything other than what they designed it for? I totally understand the concept, but I don't see how it can be actually applied (not to say that it can't, but I'm sure you understand what I'm saying...or maybe you don't LOL).
And as a side note to noobs, my advice is don't get too caught up in coding standards right off the bat. Try to do things the right way, but don't be afraid to "break the rules" if you need/want/have to; just try not to develop too many bad habits along the way.
Haha, I totally see where you are coming from its just that then these people go out there getting software development jobs and when they quit or get fired we're forced to reuse un-reusable code. Also I do agree that sometimes you shouldn't do things because thats the way you are "supposed" to. About the 3rd paragraph ye I've reused tons of view code thru my projects. Example: you write a view with 2 side buttons, one to view the next image and one for the previous... if you set the view to display images in an images array that is in the delegate then your view can only display images from that specific app. HOWEVER: if you make the view have a delegate object that it can ask for how many images are in the array and the images in an increasing order then you can easily reuse the view thru multiple projects that need to display data in that manner.
Sorry If I wrote too much and once again Im not saying you don't know what you are doing or anything along those lines Im just simply stating how such design isn't very reusable (from my point of view) so that others won't run into common problems when they are working on a big project.
Also ye n00bs shouln't get caught up on coding standards because they'll just end up pondering for hours on end if they are doing things right. With time and having to rewrite identical views to some you've previously written they will learn what it takes to write reusable code and understand the standards.
Quote:
Originally Posted by myersn024
Message disclaimer: I don't pretend to know it all, and my advice probably isn't the best. Coding is one of my hobbies, and I've been doing it for around 15 years. I try to make my code easy for me to understand since I'm the one that maintains it and uses the final product. If you like your way better or think I'm full of crap, then that's your prerogative. I fully realize that all the message thus far in this thread have been constructive criticism, and I'm not angry or trying to be defensive about anything. I'm just posing my point of view and trying to help others that may be having trouble figuring out things that I know how to do.
I'm going to toss this out there just for the sake of asking....no other reason at all......
Has anyone here ever really reused a view for anything other than what they designed it for? I totally understand the concept, but I don't see how it can be actually applied (not to say that it can't, but I'm sure you understand what I'm saying...or maybe you don't LOL).
And as a side note to noobs, my advice is don't get too caught up in coding standards right off the bat. Try to do things the right way, but don't be afraid to "break the rules" if you need/want/have to; just try not to develop too many bad habits along the way.
put it this way tho:
you get hired by a company working on a huge x86 emulator.. theres over a million lines of code and all the
class files are labelled along the lines of:
"Class1.m" and the variables inside it go along these lines:
Code:
int a, b, c;
char *str1 = "hello world";
char *str = "blah";
BOOL flag;
and imagine you had to read thru all 300 class files so you can know which file to focus on to implement the feature your boss told you to add. How many days do you think it would take you to go thru all the code and find what you are looking for as compared to a project that has good naming conventions, reusable classes, etc ?
Also in the case of apple.. if they made their table views not be reusable we would all be doomed and would have to write our own table view classes.. wouldn't that suck ? =P
Overall if you are the only one who will be working with your code and you know where everything is at and you feel you'll remember where everything is 2 years from now then get crazy with it as long as you release your product on time.
Quote:
Originally Posted by myersn024
I'm sure coding standards were created by people who were forced to figure out someone else's coding style LOL!
If you're wanting to reach the delegate from inside one of your view controllers, then you're going to have to get over being scared of that one line of code. That's how you get the singleton instance of the delegate so you can send messages to it or retrieve data from it.
Say you have a method in your app delegate called flipToBack, and you want to call it from one of your view controllers...this is how you'd do it.
That one line of code that you said you were scared of is what makes what you're wanting to do possible. All it does is get a pointer to the instance of your app delegate class. Did you even watch the video, or did you just look at the source? I thought I explained what that line of code did sufficiently.
I watched the video, implemented it, I get what you are doing. I'd give you a medal for doing it too.
I may have exaggerated a bit, but let me explain why I don't like that line. The view or view controller in MVC shoudn't know about the TwoViewAppAppDelegate, right?
Because it will never be reusable.
Lets take the UITextView, for example. To send messages UP the view hierarchy, as I understand it, the UITextView defines a prototype called UITextViewDelegate, and a public property called delegate. I believe this is the proper way to create view controllers that send signals to their parents. Right?
So the MVC way of doing that code is:
- define a prototype for the specific ViewController;
- after creating the ViewController in the app delegate, hook the TwoViewAppViewController.delegate to "self" (the app delegate);
- and in the app delegate, implement the prototype;
then from the ViewController you can do this code:
Code:
- (void) someMethod {
if ([delegate respondsToSelector: @selector(flipToBack)]) {
[delegate flipToBack]; // do something appropriate
}
}
...or not? =)
I'm new in all of this, and come from a C# background. Maybe I'm implementing event-based development to make it more familiar.
From what I've gathered from reading Apple's documentation is that the controllers are supposed to be the non-reusable part of the code. Based on that, the views shouldn't talk directly to the delegate; they should pass messages to their controllers and the controllers, in turn, pass messages to the delegate. However, no where in their documentation do they talk about how to handle delegates in the MVC schemata. My personal interpretation it is that the delegate is there for the controllers to use for, among other things, a shared resource. I base that assumption on the fact that I haven't ran across another class type for iPhone programming that has a singleton instance that can easily be accessed without creating the singleton yourself.
I think that everyone is in agreement that the view methods telling the delegate to flip views should lie in the controllers. After reading all this discussion, I've decided that I should probably re-do the tutorial to show proper MVC based design.
Actually the view controllers are allowed access to w.e the heck they want, when using MVC we simply care about having reusable models and views. Heck if you make a reusable controller then many props to you but thats barely ever possible unless you are working on doing something very generic. The view however shouldn't have direct access to the delegate, any info it needs to display or deal with should be passed to it by its view controller.
Quote:
Originally Posted by cDima
I watched the video, implemented it, I get what you are doing. I'd give you a medal for doing it too.
I may have exaggerated a bit, but let me explain why I don't like that line. The view or view controller in MVC shoudn't know about the TwoViewAppAppDelegate, right?
Because it will never be reusable.
Lets take the UITextView, for example. To send messages UP the view hierarchy, as I understand it, the UITextView defines a prototype called UITextViewDelegate, and a public property called delegate. I believe this is the proper way to create view controllers that send signals to their parents. Right?
So the MVC way of doing that code is:
- define a prototype for the specific ViewController;
- after creating the ViewController in the app delegate, hook the TwoViewAppViewController.delegate to "self" (the app delegate);
- and in the app delegate, implement the prototype;
then from the ViewController you can do this code:
Code:
- (void) someMethod {
if ([delegate respondsToSelector: @selector(flipToBack)]) {
[delegate flipToBack]; // do something appropriate
}
}
...or not? =)
I'm new in all of this, and come from a C# background. Maybe I'm implementing event-based development to make it more familiar.
Great discussion on views, controllers and app delegate
Thanks for providing the discussion/debate over the proper separation of the code. This is one piece of the iPhone puzzle I'm still not crystal clear on: should all view state be handled through the app delegate? I think the answer is yes.
When my app exits, then runs again, it should restore its state and appear as it did before (not all apps HAVE to do this, but I believe it's the suggested behavior). In this case, the app delegate is responsible for restoring the data and presenting the appropriate view.
If any data were stored in the view (scroll position, perhaps the view has two modes, or some subview is either displayed or hidden), a mechanism would need to be invented to save/restore this data: either the app delegate would know about the data (perhaps as just a blob of view data), or the view would be told to save/restore its own data.
In this case, we're talking about MVC, but at two layers. There's the app data - then there's the view data. When I'm looking at an email PDF attachment, close the app, then restart mail, I get a view of my attachment scrolled to the exact place I was before. When I am in the middle of authoring an email, close the app, then restart main, I get a view with the cursor in the right place of the body of the message, but the scrolling isn't necessarily the same. So this piece of the view state isn't persisted.
No, view state should be handled by the view controller. In VERY SMALL applications this could be the delegate.
Most complex applications that deal with tons of views would have various view controllers.
View states such as scroll position should be restored by the view controller and saved by it too. The view should only have some kind of accessor
method to determine at what point the view was scrolled to. A scroll view would have a method such as currentScrollPoint or some other accessor to access
the area where it is scrolled.
I hope all that made sense.
Quote:
Originally Posted by TheFury
Thanks for providing the discussion/debate over the proper separation of the code. This is one piece of the iPhone puzzle I'm still not crystal clear on: should all view state be handled through the app delegate? I think the answer is yes.
When my app exits, then runs again, it should restore its state and appear as it did before (not all apps HAVE to do this, but I believe it's the suggested behavior). In this case, the app delegate is responsible for restoring the data and presenting the appropriate view.
If any data were stored in the view (scroll position, perhaps the view has two modes, or some subview is either displayed or hidden), a mechanism would need to be invented to save/restore this data: either the app delegate would know about the data (perhaps as just a blob of view data), or the view would be told to save/restore its own data.
In this case, we're talking about MVC, but at two layers. There's the app data - then there's the view data. When I'm looking at an email PDF attachment, close the app, then restart mail, I get a view of my attachment scrolled to the exact place I was before. When I am in the middle of authoring an email, close the app, then restart main, I get a view with the cursor in the right place of the body of the message, but the scrolling isn't necessarily the same. So this piece of the view state isn't persisted.
I have a question. How do you solve the problem with simulated metrics, when having separate .xib files?
As you can see, I've uploaded your sample[1] with a minor modification: I added a label at the top of the screen in your settings view. This label gets covered later by the status bar.
I've been having this problem for quite a while, and the only solution I've found (so far) is NOT to use IBuilder...
It seems like all IB does is tell the view what size frame to use. IB however (for me, at least) has never removed the status bar. Usually I remove it programmatically.
Quote:
Originally Posted by dalef84
I have a question. How do you solve the problem with simulated metrics, when having separate .xib files?
As you can see, I've uploaded your sample[1] with a minor modification: I added a label at the top of the screen in your settings view. This label gets covered later by the status bar.
I've been having this problem for quite a while, and the only solution I've found (so far) is NOT to use IBuilder...