How to get frame size after autoresize is done - iphone

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

Related

UIScrollView not scrollable

I am trying to make a UIScrollView scrollable.As I've understood, the difference between the content size and the frame size makes the view scrollable to reach the other parts of the rectangle.So I've put different sizes.
This what I've done in my view controller:
- (void)viewDidLoad
{
[super viewDidLoad];
scrollView= [[UIScrollView alloc]initWithFrame: CGRectMake(0, 0, 200, 200)];
scrollView.contentSize= CGSizeMake(1000, 1000);
scrollView.scrollEnabled=YES;
scrollView.pagingEnabled=YES;
scrollView.backgroundColor=[UIColor yellowColor];
scrollView.alwaysBounceHorizontal=YES;
scrollView.alwaysBounceVertical=YES;
[self.view addSubview: scrollView];
}
But the view is not scrollable, the scroll bar isn't even there is the view.
There are some similar questions but no one made me get the solution.
I got the impression that everything I write in the viewDidLoad method is merely ignored, except for setting the color.But of course the method gets executed.
make sure to include (do this in viewWillAppear, because there are some strange issues with declaring this in viewDidLoad)
self.scrollView.delegate=self;
and also declare that your class is a UIScrollViewDelegate in your header somewhere
It looks to me as if you are trying to create a scrollview without any subviews? I guess it doesn't really want to have an arbitrary contentSize if it doesn't really have anything to show anyways. What is it exactly that you are trying to achieve?
UIScrollView class reference
I discovered that the view was scrolling, just in a different way from what I had habis with Cocoa so i didn't notice it.

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.

why might layoutSubviews NOT automatically be called on a view when its frame is set?

I have a view. It is part of a large and complex project. When the frame of my view is set, layoutSubviews is not automatically called.
Playing around with this, I tried putting the following method into my view:
-(void) setFrame: (CGRect) frame {
NSLog (#"setting frame");
[super setFrame: frame];
[self setNeedsLayout];
}
At this point, layout was redone when the frame was set, as expected. And if I commented out the setNeedsLayout line, layout was not done. Furthermore, when I click on "step into" at the line where super is called, the debugger does not step into anything. So as far as I can tell, super's setFrame method is not being overridden.
FWIW, I also did a small test project in which I changed the frame of a view. In this case, layoutSubviews was called when I did that. [setNeedsLayout was not called in my test project.] So something in my large project is changing the behavior. But I don't know what that something is.
Can anyone explain what might be going on?
EDIT: to clarify, my frame change is changing the view's height. The width is not changed.

objective c. ScrollView: how to force it redraw visible part each time user scrolls?

I've got my own dynamically changing view inside scrollview.
As my view is very big I usually redraw only it's visible part.
But when I scroll up or down drawRect method isn't being called.
I guess scroll view has a buffer to quickly react on user actions but I don't know exactly a mechanism how it works.
UPD
Thanks to Wienke, I've got a solution: to implement UIScrollViewDelegate.
I've implemented scrollViewDidScroll method:
-(void) scrollViewDidScroll:(UIScrollView *)sender {
CGRect visibleRect;
visibleRect.origin = [scrollView contentOffset];
visibleRect.size = [scrollView bounds].size;
[textField setNeedsDisplayInRect:visibleRect];
}
So every time user scrolls even a little this method redraws the whole visible part. That's bad=(
How can I redraw only... Let me call that "new region that appeared after scrolling". I guess it's much faster...
Thanks for your attention.
Have you tried assigning a scrollview delegate? The UIScrollViewDelegate protocol includes methods like scrollViewDidEndDragging, upon which you could redraw.

Change background image on ipad after rotation

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.