How to create view from a nib file in xcode? - iphone

I have the following code to create a view and put it in scrollview to allow paging
the code works fine however what I couldn't do is loading views from a nib file
in other words
I want to use "initWithNibName" instead of "initWithFrame"?
- (void)createPageWithColor:(UIColor *)color forPage:(int)page
{
UIView *newView = [[UIView alloc] initWithFrame:CGRectMake(0, 300,400)];
newView.backgroundColor = color;
[scrollView addSubview:newView];
}
Thanks alot

I know this is an old post, but I wanted to create a UIView as a separate file and add a xib so I could use it in several places in my app (almost like using it as a custom table view cell). And I couldn't get it quite right, but this post helped me get to the result I wanted.
So just if anyone wants to do it the same way, this is what I did:
Add this to the initialization code in your UIView's .m file:
- (id)initWithFrame:(CGRect)frame
{
self = [NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil][0];
if (self)
{
self.frame = frame;
}
return self;
}
Then in interface builder/xib editor you have to assign the class you created for the UIView so you can add IBOutlets.
Hope it helps someone out, cuz it took me a bit!

I think the thing you're missing is that you can set the frame of your new UIView after loading the nib. Load/Init time isn't your only shot at that. I'm also breaking the load function into its pieces, in the code below, so you can see more easily what's going on.
Observe:
NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:#"yournib"
owner:self
options:nil];
//I'm assuming here that your nib's top level contains only the view
//you want, so it's the only item in the array.
UIView *myView = [nibContents objectAtIndex:0];
myView.frame = CGRectMake(0,0,300,400); //or whatever coordinates you need
[scrollview addSubview:myView];
Don't forget that for that UIScrollView to actually scroll, you need to set its contentSize property to the size of the goods inside it, which is likely bigger than the .frame property of the scroll view itself.

Try something like this (adapted from "The iPhone Developers Cookbook", pg. 174):
UIView *newView = [[[NSBundle mainBundle] loadNibNamed:#"yournib" owner:self options:nil] lastObject];
This assumes a single view object in your .xib, but you could modify it if your .xib is more complicated.

Related

UIScrollView scrolling lags

I Have UIScrollView and a few (about 10 "posts").
Post - custom view with UILabe loaded from nib and dinamically changed frame.
So I do:
[[NSBundle mainBundle] loadNibNamed:#"AWPostShortView"
owner:self
options:nil];
// calculate frame etc (doesn't matter)
self.shortPost.frame = frame;
// Add to scrollView
[self.scrollView addSubview:self.shortPost];
self.shortPost = nil;
The problem is that "scrolling" action has lags.
I mean - scroll view follow under cursor with delay
I do not any operations, calculations etc when posts appears.
Please, advise how to optimize it
(I can't use UITableView and reuse cells coz I have different cells heights)

UIScrollView referenced both by UIViewController's 'view' property and by an outlet

I'm about to add a UIScrollView to my iPhone project and before I implement this functionality I wanted to check if my approach is the right one or if I could be violating some best practice I'm not aware of.
The tutorials I've seen generally involve adding a UIScrollView to an existing UIView and they work from there. However, I was wondering if I could spare the UIView altogether and just add the UIScrollView as the only top-level object in my nib file.
My sample project uses Xcode's View-based Application template:
Project navigator http://img542.imageshack.us/img542/5364/projectnavigator.png
I deleted the UIView top-level object from the original MySampleViewController.xib file and replaced it by adding a UIScrollView object:
Nib placeholders http://img526.imageshack.us/img526/7709/placeholderobjects.png
Now my nib file only shows this object in the canvas:
Canvas http://img233.imageshack.us/img233/4063/scrollview.png
Then I created the link from the UIViewController's view outlet to the UIScrollView.
Now, if I wanted to programmatically manipulate the contents of the UIScrollView I can use this code:
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];
// Solution B: With the following line we avoid creating an extra outlet linking to the UIScrollView top-level object in the nib file
UIScrollView *scrollView = (UIScrollView *)self.view;
for (int i = 0; i < colors.count; i++) {
CGRect frame;
//frame.origin.x = self.scroller.frame.size.width * i; // Solution A: scroller is an IBOutlet UIScrollView *scroller;
frame.origin.x = scrollView.frame.size.width * i; // Solution B
frame.origin.y = 0;
//frame.size = self.scroller.frame.size; // Solution A
frame.size = scrollView.frame.size; // Solution B
UIView *subView = [[UIView alloc] initWithFrame:frame];
subView.backgroundColor = [colors objectAtIndex:i];
//[self.scroller addSubview:subView]; // Solution A
[self.view addSubview:subView]; // Solution B
[subView release];
}
//self.scroller.contentSize = CGSizeMake(self.scroller.frame.size.width * colors.count, self.scroller.frame.size.height); // Solution A
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * colors.count, scrollView.frame.size.height); // Solution B
}
In order to implement Solution A the scroller outlet must be linked to the nib's UIScrollView as well, and the Connections Inspector looks like this:
Connections Inspector http://img228.imageshack.us/img228/8397/connectionsj.png
Solution A requires an outlet and this means having two connections to the UIScrollView: the UIViewController's own view outlet and MySampleViewController's scroller outlet. Is it legal and/or recommended to have two outlets pointing to the same view?
Solution B only involves UIViewController's view outlet linking to the view, and using this line:
UIScrollView *scrollView = (UIScrollView *)self.view;
My questions:
Do I incur in some sort of violation of Apple's design guidelines by using one of these two solutions?
Should I stick to the UIScrollView within a UIView solution?
Is there any other way to implement this?
Thanks!
P.S. Sorry for the syntax highlight, SO didn't recognize the use of the 'objective-c' tag
No I think you are fine either way.
I would, I don't think a UIView has any significant cost, plus what if you want to add a page control? and you don't have to cast the controller's view to a UIScrollView every time you need it.
Looks like you have it under control to me.
Solution A requires an outlet and this means having two connections to the UIScrollView: the UIViewController's own view outlet and MySampleViewController's scroller outlet. Is it legal and/or recommended to have two outlets pointing to the same view?
It standard to have IBOutlets to any view defined in your .nib that you want to access directly from your view controller.
If you don't want two outlets you could give the scroll view a tag then find it like so:
UIScrollView *myScrollView = (UIScrollView *)[self.view viewWithTag:1]
Then you only have the view as an outlet, but I would just add the extra outlet. Just make sure you set them to nil in your viewDidUnload.
Also you don't have to retain the scroll view (if you are even still using retain/release). Since the scroll view is inside your view controller's view it keeps a reference so you can have your scrollview's property by assign or week if your using ARC.
Hope that helps.

ImageView Scrolling along with the tableview

In my application,i created an imageview on the above the tabbar.I want to display some images here for displaying some adds there.
What my actual problem is...i added this on my table view and whenever i am scrolling the table view ,my imageview is also scrolling.Please help me in this
Thanks in advance.Here is my code
UIImageView *currentLocationImageView = [[UIImageView alloc] init];
NSURL *url1 = [NSURL URLWithString:#"http://imgsrv.995themountain.com/image/kqmt2/UserFiles/Image/SiteGraphics/MTNVideos360x80.jpg"];
UIImage *img1 = [UIImage imageWithData: [NSData dataWithContentsOfURL:url1]];
NSURL *url2 = [NSURL URLWithString:#"http://download.xbox.com/content/images/35f6c527-fb73-40d3-bcb9-bdea2680bc03/1033/banner.png"];
UIImage *img2 = [UIImage imageWithData: [NSData dataWithContentsOfURL:url2]];
NSArray *images = [NSArray arrayWithObjects:img1, img2, nil];
[currentLocationImageView setAnimationImages:images];
[currentLocationImageView setAnimationRepeatCount:0];
[currentLocationImageView setAnimationDuration:5.0];
currentLocationImageView.frame = CGRectMake(0.0, 340.0, 320.0, 30.0);
//self.tableView.tableFooterView = currentLocationImageView;
[currentLocationImageView startAnimating];
[self.view addSubview:currentLocationImageView];
Without seeing more code, it looks as though you may be using a UITableViewController instead of a UIViewController. The difference between the two is important in the case of your last line [self.view addSubview:currentLocationImageView]. What that does in a UIViewController is adds it to the view that would be containing the tableview and the imageview. However, in a UITableViewController the self.view property holds the tableview itself, therefor, it ads your image view as a subview of the tableview, subjecting it to the tableview's scrolling behaviour.
What you can do is change from using a UITableViewController (probably going to be trivial for your application, but may be less than trivial depending on why you opted to use it in the first place); and you'll also need to explicitly create the tableview, and add it to the backing view of the UIViewController subclass you're writing—akin to how you're adding the imageview above.
Hope this helps.

loadNibNamed, view shifted up?

I am using loadView to programatically setup a UIViewController subclass and was wondering if I am getting it right. When I look at my "Interface.xib" in Interface Builder its view says 0,20,320,460 with the Status bar at the top. My question is when I build the application the view is shifted up (i.e. ignoring the Status bar). I am correcting this by setting the views frame, but am a little curious why its not coming in from the xib file?
- (void)loadView {
NSLog(#"HYBRID UI: %s", __PRETTY_FUNCTION__);
NSArray *nibArchive = [[NSBundle mainBundle] loadNibNamed:#"Interface" owner:self options:nil];
UIView *nibView = [nibArchive lastObject];
[nibView setFrame:[[UIScreen mainScreen] applicationFrame]];
[self setView: nibView];
}
cheers gary
Maybe the view, when loaded from main bundle, doesn't get it's bound in the superview context. Hence getting (x, y) = (0, 0).
You should try to move your view to whatever (x, y) in your xib and watch if this changes anything.

How to set background image of a view?

I am a beginner at Obj-C/Cocoa Touch/iPhone OS.
I wish to have a background for my app with different images everytime the the view is called.
Say I have 10 images. I 've used it like this:
//random image generation
NSString* imageName;
int aRandomNumber = arc4random() % 10;
imageName =[NSString stringWithFormat:#"g%d.jpg",aRandomNumber];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:imageName]]];
NSLog(#"aRandomNumber is %d", aRandomNumber);
//random image is generated
Its working fine
Now, say I have text labels on my view and the text isn't displaying correctly due to image colors.
How can I make it a little transparent? (I guess in Interface Builder its called alpha.)
Say my image isn't 320x480. How do I set it to fill the entire view?
How can I do it with UIView/UIImageView?
I found initWithHue:saturation:brightness:alpha: in the documentation but it's not working:
self.view.backgroundColor = [[UIColor alloc] initWithHue:0.0 saturation:1.0 brightness:1.0 alpha:1.0];
Please Help!
A friend suggested........
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:imageName]]];
..........he told it's more efficient because it doesn't save the image in the cache.
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"imageName.png"]];
more info with example project
Besides all of the other responses here, I really don't think that using backgroundColor in this way is the proper way to do things. Personally, I would create a UIImageView and insert it into your view hierarchy. You can either insert it into your top view and push it all the way to the back with sendSubviewToBack: or you can make the UIImageView the parent view.
I wouldn't worry about things like how efficient each implementation is at this point because unless you actually see an issue, it really doesn't matter. Your first priority for now should be writing code that you can understand and can easily be changed. Creating a UIColor to use as your background image isn't the clearest method of doing this.
use this
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"Default"]];
simple way :
-(void) viewDidLoad {
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background.png"]];
[super viewDidLoad];
}
It's a very bad idea to directly display any text on an irregular and ever changing background. No matter what you do, some of the time the text will be hard to read.
The best design would be to have the labels on a constant background with the images changing behind that.
You can set the labels background color from clear to white and set the from alpha to 50.0 you get a nice translucent effect. The only problem is that the label's background is a stark rectangle.
To get a label with a background with rounded corners you can use a button with user interaction disabled but the user might mistake that for a button.
The best method would be to create image of the label background you want and then put that in an imageview and put the label with the default transparent background onto of that.
Plain UIViews do not have an image background. Instead, you should make a UIImageView your main view and then rotate the images though its image property. If you set the UIImageView's mode to "Scale to fit" it will scale any image to fit the bounds of the view.
You want the background color of your main view to be semi-transparent? There's nothing behind it... so nothing will really happen however:
If you want to modify the alpha of any view, use the alpha property:
UIView *someView = [[UIView alloc] init];
...
someView.alpha = 0.8f; //Sets the opacity to 80%
...
Views themselves have the alpha transparency, not just UIColor.
But since your problem is that you can't read text on top of the images... either:
[DESIGN] Reconsider the design/placement of the images. Are they necessary as background images? What about the placement of the labels?
[CODE] It's not exactly the best solution, but what you could do is create a UIView whose frame takes up the entire page and add some alpha transparency to it. This will create an "overlay" of sorts.
UIView *overlay = [[[UIView alloc] init] autorelease];
overlay.frame = self.view.bounds;
overlay.alpha = 0.2f;
[self.view addSubview:overlay];
... Add the rest of the views
You can set multiple background image in every view using custom method as below.
make plist for every theam with background image name and other color
#import <Foundation/Foundation.h>
#interface ThemeManager : NSObject
#property (nonatomic,strong) NSDictionary*styles;
+ (ThemeManager *)sharedManager;
-(void)selectTheme;
#end
#import "ThemeManager.h"
#implementation ThemeManager
#synthesize styles;
+ (ThemeManager *)sharedManager
{
static ThemeManager *sharedManager = nil;
if (sharedManager == nil)
{
sharedManager = [[ThemeManager alloc] init];
}
[sharedManager selectTheme];
return sharedManager;
}
- (id)init
{
if ((self = [super init]))
{
}
return self;
}
-(void)selectTheme{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *themeName = [defaults objectForKey:#"AppTheme"] ?: #"DefaultTheam";
NSString *path = [[NSBundle mainBundle] pathForResource:themeName ofType:#"plist"];
self.styles = [NSDictionary dictionaryWithContentsOfFile:path];
}
#end
Can use this via
NSDictionary *styles = [ThemeManager sharedManager].styles;
NSString *imageName = [styles objectForKey:#"backgroundImage"];
[imgViewBackGround setImage:[UIImage imageNamed:imageName]];