Change background image on ipad after rotation - iphone

I show bg of my app using UIImageView. To support correct interface rotation i write layoutSubviews method. In this metod .frame property changes correctly, but when i try change image of UIImageView just like this:
view = [self viewWithTag:1002];
((UIImageView *)view).image = [UIImage imageNamed:#"portrait.png"];
nothing changed. Did I do something wrong or is it impossible to change image of UIImageView in layoutSubviews method?

try this
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
// change background here
}

You manage the rotation of your views by using a UIViewController (be sure to check out the docs here: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html). If you implemented a UIViewController for your UIImageView you could set the image in the viewDidLoad: method.
You shouldn't override the layoutSubviews: method to perform this action. layoutSubviews:is to do what it says in the name - it should perform the positioning and sizing of any subiews that this view currently has. You shouldn't need to override this method unless you wanted to do some special custom laying out of the subviews and is called in the run loop when the UIView is set to "requires resizing".
I strongly suggest you set your image from from some other location in the code. If you want the image to change when the view is rotated, you could set the image in the - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation method of a UIViewController subclass.

Related

Adding UIView from class without frame

Is there a way to add a UIView from a function (in this case, within a statically built library) to a view without passing a frame for the view itself.
Paypal's library achieves this, and I was wondering how the implementation would go.
I don't want to change the root controller, I would just like to add my view over the current controller.
in the style of
[something addSubview:myNewView];
Where something is a view that I don't have access too.
Yes. You simply use the default init method instead of initWithFrame::
MyView *mySubview = [[MyView alloc] init];
[otherView addSubview:mySubview];
Note that this will result in a frame at origin (0/0) with zero size for mySubview and though it would be invisible. You could either specify the frame later, once you know it, or MyView can override the init method and pass a default frame to [super initWithFrame:defaultFrame].
While DrummberB's answer is correct, the view would not show up anywhere because a view initialized without a frame defaults to a frame of CGRectZero. Sooner or later you will need to assign a frame to the view.

How to get frame size after autoresize is done

I wonder, how and when (viewDidLoad, viewWillAppear, viewDidAppear) can I get a UIViews frame size that was autoresized to fit its partent view?
It's not clear from your question why you want it but I imagine it is to layout your sub views. Luckily Apple knew you would want to do that and implemented -(void)layoutSubViews see this: When is layoutSubviews called?
I tried layoutSubviews, but it gets called more than once which is a problem when I need the auto sized frame in order to create a CGContext to draw into.
The solution I used was to expose an init method on my custom UIView for its parent view controller to call in its viewWillAppear.
I wish there was a way to accomplish this all within the custom UIView's implementation, but it eludes me (and Google and Apple's docs and SO).
- (void)viewDidAppear:(BOOL)animated {
CGFloat uIViewWidth = self.uIView.bounds.size.width;
CGFloat uIViewHeight = self.uIView.bounds.size.height;
CGRect uIViewSize = CGRectMake(0, 0, uIViewWidth, uIViewHeight);
}
NSLog(#"%f; %f; %f; %f;", yourView.frame.origin.x, yourView.frame.origin.y, yourView.frame.size.width, yourView.frame.size.height);
this is how you can get frame of your view

iPhone: Resizing in drawRect:

I have a UIView based control which I need to resize depending on various criteria and properties of the control. I'm not sure if the way I'm doing it is the best way but so far it's the only one I've found that seems to work. Because the size of the control is dependant on various properties, I cannot set the size in a constructor.
I have a method called setupControl: which contains all the code to finish the setup based on the properties set. I don't want setupControl: called manually, so in drawRect I detect if I need to call it and then queue a selector like this:
[self performSelector:#selector(setupControl)withObject:self afterDelay:0];
return;
At the bottom of setupControl: I then do:
[self setNeedsDisplay];
self.hidden = NO;
I've also overridden the initWithFrame: and initWithDecoder: constructors so that they set the UIView to be hidden to start with until the setup code is executed. The idea being to eliminate any "flashes" on the display as the control resizes.
As I said this works fine, the controls can be drawn ay size is the xib file and then set themselves to the correct size at run time.
My question is whether this method of queuing a selector, exiting the drawRect: and then using a setNeedsDisplay is the only way to do this? O is there some method I haven't found that I can override? or something else?
What you probably want to override is layoutSubviews rather than drawRect as you're changing the layout, not implementing custom drawing.
You may also have to use a custom setter for any properties that change the size of the view and call [self setNeedsLayout] in the setter to make sure your layoutSubviews method is called before your view size is computed.

Displaying CAEAGLLayer in a UIView or CALayer

Rather new to trying to get OpenGL ES working on the iPhone, but I've created a working demo from an OpenGL template and wanted to add it to another App which is a standard UIViewController App. After searching around it seems that I can't addSubview a CAEAGLLayer to a CALayer aka UIView. How would I go about doing this? Or am I completely wrong in what I'm doing.
Cheers for any help
Simply use a UIView and add:
+ (Class)layerClass {
return [CAEAGLLayer class];
}
That UIView is now a CAEAGLLayer, so you can add that view as a subview of another UIView like normal.
What I actually had to do was change in the EAGLView -initWithCoder to -initWithFrame and make the appropriate changes to the method to handle the frame. Once I did that and initialised the view with initWithFrame it worked.
I believe you are looking for CALayer's insertSublayer methods or the addSublayer method.

iPhone SDK: How to trigger drawRect on UIView subclass after orientation change?

I am subclassing a UIView and overwrite the drawRect method. I'm noticing that the view's drawrect is only being called when the view first loads. After that it is never called again. How to I make sure it gets called after an orientation change? I've tried calling setNeedsDisplay on the view before and after the rotation and that doesn't do it.
[myView setContentMode:UIViewContentModeRedraw];
You can set this in IB as well (i.e., set mode to "redraw")
This was a bug related to something completely different. setNeedsDisplay does indeed cause drawRect to be called.
to answer this and the other 94,000 similiar questions about view rotation/drawrect funkiness,
-(id)initWithFrame:(CGRect)frame
{
if(self=[super initWithFrame:frame]) {
self.autoresizesSubviews=YES;
self.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
}
return self;
}