How to resize other subviews and parent view when one subview size changes - iphone

I have a view which is similar to mail app. I have a scroll view and in that many other subviews. When the user clicks on any textview, it expands to show the text in it. e.g. "to" field in mail. I would want to resize the other subviews such that it starts below the expanded region. How can I do that.
I created the view through IB and I marked it for flexible top margin to facilitate this. But nothing happens automatically and hence I was wondering if I need to call sizethatFits/setneedsLayout.

When the subview resizes, call [[self superview] setNeedsLayout]. In your superview, implement -layoutSubviews to do the actual layout. You'll have to calculate everything yourself. Fixed/flexible margins are relevant to resizing the superview, not on peer views. The default -layoutSubviews does nothing at all; it just gets called at appropriate times.
If you need to force layout to happen at a particular point, then you can call -layoutIfNeeded on yourself or your superview. Read the docs on how this method works. Generally speaking you don't need to call this, though. It will usually get called at the appropriate time if you just use -setNeedsLayout.

Related

Is it possible to avoid SuperViews when hitTesting?

Basically, I want to be able to click all the Subviews in the Image below...
I want to be able to tap the Subviews of View B but View A is in the way even though View A Subviews are not blocking the views below. Is this possible? In other words I want to be able to tap through the transparent parts of a view even though its frame/bounds cover that area. View B is under View A in a ScrollView.
thanks,
austin
The solution is to subclass View A (if it's not a custom view already) and override pointInside:withEvent.
Return YES if the specified point is inside one of View A's sub-views, or NO otherwise. When pointInside:withEvent returns NO the system will continue to try other views until it finds one that claims the point is inside it, then it will call hitTest:withEvent to see which inner-view to send the touches to (the default behaviour).

how to invalidate uiview constraints

I would like to invalidate a uiview constraints from code to force all fields to relayout based on a specific change in the view.
For example, suppose i have two UILabels that are given a fixed VerticalSpace constraint. And in some user event i am resizing the label that is on top. I would like to be able to force the constraint to invalidate from code.
This is the first time i use constraints and i do not understand how i can do this from code. I know that when the device is rotated constraints on UIViews are invalidated.
You call setNeedsLayout on the relevant view, typically your view controller's .view. :
[self.view setNeedsLayout];
You're not really invalidating the constraints, that is a slightly different thing used for custom views which may need to remove and recalculate constraints based on other changes. What you're doing is letting the view know that some of the factors it used to calculate its layout have now changed. The constraints are still valid, but the results have changed.
To animate to your new layout, you can call layoutIfNeeded inside an animation block.

Automatically reposition views after UITextview resizes - iOS

For a simple example lets say I have a UITextView with a Button underneath it. These two controls are siblings both embedded in a parent UIView.
I now change the text within the UITextView and resize it accordingly. Is there a way to make the button automatically move to have the same relative distance to the bottom of the UITextView? This may seem trivial for this case, but I will have a longer hierarchy with multiple UITextViews that change and it would be nice not to have to calculate the height of every object manually.
One way to approach this would be with a table view: if you place each of your text views within its own table view cell, the table view will automatically calculate its total height from individual calls to its delegate’s -tableView:heightForRowAtIndexPath: method and lay itself out accordingly. Whenever the height of one of your text views needs to change, you can call -reloadData on the table view to make it lay itself out again. A disadvantage of this approach is that it’s really difficult to animate the height changes; if that’s essential to the effect you’re going for, I’m afraid you’re stuck with doing the entire layout manually.
Try the autoresizingMask property of UIView.

determine if uiview is displayed

is there a possibility to determine if an uiview obj is going to be displayed. imagine: you have 2 uiviews in an uiscrollview. now you are going to switch per gesture from the first view to the second. the first view now is NOT in the viewport. now you are going to go back to the first view. and now I want to be notified that this view is in viewport, or is redisplayed. the same has to be for the second view. I have not found any callback or something like this.
You make sure your UiViewController overrides viewWillAppear: (before it appears this method is called) or viewDidAppear: (after this method is called).
See: http://developer.apple.com/iphone/library/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewWillAppear:
That depends what you mean by "switch". If one view is just scrolled out of the visible area of the scrollview, but still remains attached as a subview to it, then you may want to check if the bounds of your view overlap those of the scrollviews visible area.
You could do this by using UIScrollView Delegate's scrollViewDidScroll: method to implement a check for overlaps while the user is scrolling.
If however your view is actually removed from the viewstack, then you may want to subclass UIView and implement willMoveToSuperview: to check if the view has been added to the scrollview again.

Nested UIScrollView does not paint

I am building an application which allows the user to view and edit data on a daily basis. To accomplish this i have created a view in Interface builder which contains all of the daily data, and i "tile" this view within an appropriately sized UIScrollView to allow the user to swipe between the days. The view contains two UITextFields, a couple UILabels, and a UITextView. At any given time i have five instances of this view which i re-position around and update the data for the appropriate position.
Everything works great with the exception of the UITextView. The UITextView does not display its Text property until the user has interacted with it (I'm guessing this triggers a redraw).
Is there an easy way to get the UITextView to "paint" its content when its not on screen (but still added as a subview to another view)?
One thing you can try, which is what I just did to fix the same problem, is hook into the parent scrollview's scrollViewDidScroll delegate function. Then in that function, send a message to the UITextView that would force a redraw, my method was setting its frame to the same frame. It's pretty brute force but it's better than nothing.