UIScrollView autoresize contentSize? - iphone

Fair warning, I'm fairly new to iOS and may be missing something obvious.
I have a UIScrollView with a few fields and those fields height can change (UITextView that stretches to fit text, collapsable fields etc). Obviously I want the scrollview contenSize to fit the content in order to allow scrolling.
Right now I have it set to re-calculate and set the contentSize every time something changes, which works fine but is there a better way to do it? In other words, if another developer now adds a field and doesn't remember to add it to the re-calculation function, unless I'm mistaken, the scrollview contentSize will be wrong even though the field is on the scrollview? Is there no way to have it "automatically" resize with it's content change?

Yes, there is a better way to accomplish this with autolayout. Apple has a very good document for using autolayout with scrollviews here. I prefer the pure autolayout approach, however in order to apply that approach you must ensure that the size of your fields are not dependent on the size of the scrollview, which makes sense. However make sure that your constraints extend to all the sides of the scroll view, so that the scrollview can determine the size of it's content.
(ie #"H:|[textView(==view)]|" and #"V:|[textView(50)]|" where '|' denotes the scrollView of which the textView is a subview and '==view' just specifies that the width of the textView must be the same as that of the view 'view'.)

If autolayout is an option for you then go with it - as Tyler stated autolayout abstracts the resizing away for you! :)
Unfortunately i have no experience yet with autolayout, so I can't tell you more about that.
Without autolayout there is no better way as far as i know.
There's nothing like "sizeToFit" or "sizeThatFits" that would take over the task of resizing the content size automatically. You have to re-calculate the content size yourself.
For that purpose either use your custom method for this re-calculation task or check out some 3rd-party categories on UIScrollView that allready have this implemented and abstracted away for you.
For example: UIScrollView+MTUIAdditions.m
(see the implementation for UIScrollView (MTUIAdditions))

The best solution
//autoresize scrollView
CGFloat scrollViewHeight = 0.0f;
CGFloat scrollViewWidth = 0.0f;
for (UIView *view in self.scrollView.subviews) {
CGFloat height = (view.frame.size.height + view.frame.origin.y);
scrollViewHeight = ((height > scrollViewHeight) ? height : scrollViewHeight);
CGFloat width = (view.frame.size.width + view.frame.origin.x);
scrollViewWidth = ((width > scrollViewWidth) ? width : scrollViewWidth);
}
[self.scrollView setContentSize:(CGSizeMake(scrollViewWidth, scrollViewHeight))];

Related

Changing frame of an NSView inside NSScrollView ends up with weird values

I'm running into a weird issue with my code and I hope someone else has better ideas on how to handle this.
**Summary of what I want to achieve: **
I have an editor that looks like this:
On the right side I have an inspector panel where I can manually change the frame of the currently selected view (which sits inside another NSView that's the document view of an NSScrollView).
**Summary of implementation: **
The main view inside the NSScrollView doesn't directly use autolayout, because I need to be able to set the frame manually, I leave the translatesAutoresizingMaskIntoConstraints property to true (default value) for all the subviews inside the NSScrollView. So I end up with constraints automatically created when I set the frame.
The problem:
When I set the frame, to let's say (1, 0, 100, 100) for some reason the autolayout engine will take in account the magnification value of the NSScrollView and will readjust the frame, so the final frame might end up looking like (1.74, 0, 100, 100). While I do understand this, the question is, can I disable this behavior? Is it possible to have frame value increments of 1.0 while making sure Autolayout doesn't screw the final frame regardless of the NSScrollView magnification value?
Thank you!
Autolayout views inside a magnified NSScrollView can give very strange values at times, and I haven't really figured out when and why.
I have approached a similar problem by adjusting the views' position manually according to magnification of superview, or by subclassing them and writing a method for them to take the magnification into account.
So, for example:
CGFloat factor = 1 / magnification;
element.frame = NSRectMake(x * factor, y * factor, ...);
Hope this helps.

Trying to update parent view frame according to UILabel's text size

I have a view and inside it I have a UILabel. I want the view to change its width according to the length of the text.
What I tried is to first perform SizeToFit() on my UILabel, hoping this will change its frame, and then put the labels frame into the view's frame.
This doesn't work, I guess because of auto layout restrictions.
This is the code of what I tried:
private func example(){
self.labelInsideView.sizeToFit()
viewThatContainsLabel.frame = labelInsideView.frame
self.layoutIfNeeded()
}
It seems pretty obvious that this won't work, because I am pretty sure size to fit does not change the frame. Is there any way to achieve this?
Make an IBOutlet of your UIView's width constraint and then simply change the width constraint constant to the width of UILabel
self.labelInsideView.sizeToFit()
self.widthConstraintOfView.constant = labelInsideView.frame.size.width
self.layoutIfNeeded()
Why are you even using this function. Your view should have constraints.
Leading = Top = Bottom = 8 and Trailing >= 20
Your label should have all the constraints equal to 5.
Now try and add any text in your Label and you'll get updated frame of the view without using this function. Just try this once.

how to scroll scrollview horizontally

hi i am new to iphone.I need to scroll scrollview horizontally instead of vertical.Is it possible to scroll horizontally.If it possible pls post link consist sample example.Thank u in advance.
you can use following code
[myscrollview addSubview:imgButton];
x = frame.origin.x;
y = frame.origin.y+80;
[myscrollview setContentSize:CGSizeMake(x,y)];
in that each time you add a new button/Image increase content size Y position and also make set scroll vertical false.
EDIT: Here is the link to your question.
It's hard to answer you without a concrete example. In general, the scrolling directions of a UIScrollView are defined by it's "contentSize" property. So if you have a label (myLabel) which is wider than your scrollView (myScrollview) you could write this:
myScrollview.contentSize = CGSizeMake(myLabel.frame.size.width, myScrollview.frame.size.height);
//Next line is rather optional, should be already set by default
myScrollview.scrollEnabled = YES;
If you want an example, here the sample codes are.
As Phlibbo said, the contentSize of scrollView will decide the direction of that.

UILabel inside custom UITableViewCell not drawing at the correct size

I have a custom table cell which contains a number of UILabels. At runtime, I am adjusting the height of the labels to fit their contents using sizeWithFont:constrainedToSize:lineBreakMode: and repositioning them accordingly. The last label in the cell contains a large amount of text, causing it to wrap, and I'm having a very odd problem. Although the sizeWithFont call returns the correct size, and I'm setting the UILabel's frame to that height, it draws a couple of lines short. This screenshot illustrates what I'm talking about:
In this example, the height of the full block of text should be 90 (as checked in Interface Builder), and that's what returns from sizeWithFont. It's also the height that the UILabel's frame is set to, which I have verified by logging and also by stopping execution and inspecting the value. However, as you can see, it's clearly not drawing the full 90 pixels high, although it's correctly allocating the space for it (the thin black line above 'Edited' is the table cell border). I'm completely perplexed. If anyone can offer some insight as to why it's behaving this way, I would be very grateful.
At last, a solution!
Turns out that the cell does layout twice -- once during heightForRowAtIndexPath, which is where I tweak all the heights of the subviews and the cell, and later during some untraceable transaction originating in __CFRunLoopDoObservers. How did I trace this? I added a layoutSubviews override to my custom table view cell class so I could breakpoint it.
During the second pass, the last UILabel subview was getting set to a shorter height than I set it to, probably in accordance with some arcane autoresizing rules. (Yes, I tried tweaking all of those settings first, with no success.) As it turns out, merely doing nothing in layoutSubviews disabled this framework behavior, allowing me to completely control how my views draw.
With iOS 8 it doesn't work anymore like this. Implementing layoutSubviews alone doesn't do the trick, because the layout of subviews have already changed when the method is called.
I have found 2 solutions:
adding NSLayoutConstraint to layout the subviews programmatically
implementing subview's layoutSubviews and change the frame
An example für solution 2:
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect frame = self.frame;
frame.size.height = 39.f;
self.frame = frame;
}
I've fought with similar problems. It was to do with other properties being set in previous incarnations of the cell. To find it / prove it I changed the reuseidentifer for the offending cell to make sure it was a unique cell.

How to change the width of the row of a UITableView

Can we resize the width of the row of a UITableView.
What exactly are you trying to accomplish?
I'm not 100%, but I am pretty sure each row is going to be with same width as the parent table. However, if you have a custom UITableViewCell, you can make it transparent, and organize your objects on the cell's view to mimic a different sized cell. For example if you wanted a cell to be 50px less wide than the other cells and indented, you could place a white UIView on the transparent cell, make it 50px less wide than it should be, and position it to the right.
Make sense?
I understand this is an old question, but I need a table cell to be less than the width of the screen, but still be scrollable by touch on either edge, and the cell highlight not to be full width.
I overrode the UITableViewCell setFrame method, like so:
- (void) setFrame:(CGRect)frame {
if (frame.size.width > 540.0f) {
frame.origin.x = (frame.size.width-540.0f)/2.0f;
frame.size.width = 540;
}
[super setFrame:frame];
}
I guess this is a slightly hacky solution, but it works a treat!
Hope this helps someone.
Only if you fit the whole table into a smaller area.