I have an UIImageView in an UIScrollView,the imageView's size is 300 * 500,the scrollview bounds is 300 * 300.I set the contentSize 300*500 for scrollview.When i scroll left or right,that is ok,the UIScrollViewPanGestureRecognizer not work because of the width is equal between contentSize and bounds.
When I scroll up or down,even if scrollview's contentoffsetY is 0 or the max 200,the UIScrollViewPanGestureRecognizer has been recognized.I don't want the UIScrollViewPanGestureRecognizer to be recognized at the edge as the super view of the scrollview should handle it.
Hown can i do that?
Related
I have a tableView with a tableHeaderView that is assigned through a nib file. This tableHeaderView contains a TextView (orange background) that is sized with a height constraint using sizeThatFits.
let textViewSize = titleView.sizeThatFits(CGSize(width: titleView.frame.size.width, height: CGFloat(MAXFLOAT)))
textViewHeightConstraint.constant = textViewSize.height
The constraints of this header view are setup to properly drive it’s height.
When the tableView sizes the frame for the tableHeaderView i am getting very strange results from the headerView.systemLayoutSizeFitting when scrolling in the UITextView is no enabled.
if let headerView = tableView.tableHeaderView {
let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
var frame = headerView.frame
frame.size.height = height
if headerView.frame.height != height {
headerView.frame = frame
tableView.tableHeaderView = headerView
headerView.setNeedsLayout()
headerView.layoutIfNeeded()
}}
If scrolling in the textView is enabled the tableHeaderView scales as expected, but the textView is cutting off the top line.
If scrolling for the textView is disabled (desired setting) then the height for this headerView is calculated to be larger than the size required. The length of text seems to multiply this effect.
I should also add that the TextView is being assigned attributed text with various paragraph and line spacing options.
Any suggestions as to what could be going on are much appreciated.
I have resolved my issue. I am still not sure why the above problems were occurring, but when I applied the header view in a storyboard (vs loading it in via a nib file and assigning it to tableView.tableHeaderView at runtime) all of my autolayout issues disappeared.
Still would like to know why it was mis-behaving and if there is a way to get my table header views to work through a xib files
The goal: Have a scroll view that displays an array of uiimageviews (photos) that you can horizontally scroll through them
How I understand to do this: Make the frame (CGRect) of each uiimageview the height and width of the scroll view, the y value to 0 on each, and set the first imgViews x value to 0. For every imgView after that, add the width of the scrollview to the x value. In theory, this would line the imgViews (Photos) up next to each other horizontally and not allow for any vertical scrolling or zooming, purely a horizontal photo viewer.
The storyboard setup: I am creating my scrollview in a xib file (It’s a custom uiCollectionViewCell), with these constraints:
— Top space to cell (0)
— Trailing space to cell (0)
— Leading space to cell (0)
— Height of 400
— Bottom space to a view (0)
—— (See Below for img)
Laying out the UIImgViews:
func layoutScrollView() {
for (index, img) in currentImages.enumerate() {
let imgView = UIImageView(frame: CGRect(x: CGFloat(index) * scrollView.bounds.width, y: CGFloat(0), width: scrollView.bounds.width, height: scrollView.bounds.height))
imgView.contentMode = .ScaleAspectFill
imgView.image = img
scrollView.addSubview(imgView)
scrollView.contentSize = CGSize(width: imgView.frame.width * CGFloat(index), height: scrollView.bounds.height)
scrollView.setNeedsLayout()
}
}
My suspicion: I suspect the issue is stemming from the auto layout constraints i’ve specified, but (considering Im asking a SO question) not sure
If there is a better way to do this (really the correct way) please let me know! I have been trying to wrap my head around this for a few days now.
I appreciate all responses! Thanks for reading
EDIT #1
I tried paulvs approach of setting setNeedsLayout & layoutIfNeeded before the "for" loop, and still no luck. Here is (out of three images selected) the second photo displaying. It seems that both the first and second photos are way longer than the content view and that would move the middle view over (Squished).
Your code looks fine except for a few details (that may be causing the problem):
Add:
view.setNeedsLayout()
view.layoutIfNeeded()
before accessing the scrollView's frame (a good place would be before the for-loop).
This is because when using Autolayout, if you access a view's frame before the layout engine has performed a pass, you will get incorrect frames sizes/positions.
Remove these lines from inside the for-loop:
scrollView.contentSize = CGSize(width: imgView.frame.width * CGFloat(index), height: scrollView.bounds.height)
scrollView.setNeedsLayout()
and place this line after (outside) the for loop:
scrollView.contentSize = CGSize(width: imgView.frame.width * CGFloat(currentImages.count), height: scrollView.bounds.height)
i have a view inside a viewController, i wanted to start the smaller view outside the viewController in the left, and animate it to the centre when i press a button. so i made it like this:
override func viewDidLayoutSubviews() {
smallView.center = CGPointMake(smallView.center.x - 400, smallView.center.y)
}
And it works perfectly!, the problem is i have a text view inside that smaller view, and every time i start editing it it jumps outside of the main viewController right where it was, and i have to press the button again to bring it inside.
How to fix this?
PS: i tried positioning it to the centre when i start editing the text view like this:
func textViewDidBeginEditing(textView: UITextView) {
smallView.center = CGPointMake(smallView.center.x + 400, smallView.center.y)
}
But it doesn't work. and the method is connected to the textView properly(delegate)
PS2: i also have imagePickerController inside my viewController.
OK, as you're using Auto Layout.
The first rule of Auto Layout (you will see this in any Auto Layout book) is that you absolutely cannot touch the frame or center of a view directly.
// don't do these
myView.frame = CGRectMake(0, 0, 100, 100);
// ever
myView.center = CGPointMake(50, 50);
You can get the frame and center but you can never set the frame or center.
In order to move stuff around using Auto Layout you need to update the constraints.
For instance if I set up a view called myView and want it to grow and shrink in height I would do something like...
Set the top constraint to the superview at 0.
Set the left constraint to the superview at 0.
Set the right constraint to the superview at 0.
Set the height constraint to 50 (for example) and save it in a property called heightConstraint.
Now to animate the change in height I do this...
self.heightConstraint.constant = 100;
[UIView animateWithDuration:1.0
animations:^ {
[self.view layoutIfNeeded];
}];
This will then animate the height from 50 (where it was when I set it) to 100.
This is the same for ANY animation of views using Auto Layout. If (for instance) I had saved the left constraint I could change that and it would increase and decrease the gap from the left edge of the superview to myView.
There are several really good tutorials about AutoLayout on the Ray Wenderlich site. I'd suggest you take a look at them.
Whatever you do, I'd strongly suggest not just disabling Auto Layout. If you don't know how to use Auto Layout then you will very quickly fall behind with iOS 8 and the new device sizes.
Hierarchy is a fullscreen landscape container UIScroll. Inside are multiple fullscreen pages made up of uiscrollviews with images inside - this allows paging plus pinching /zooming of the inner scrollviews. You can scroll up and down.
I want to resize the width of the container scrollview and have the nested uiscrolls and images within them resize proportionally and dynamically to the new width and height.
My outer scroll has autoresize to yes, my inner scrolls have the same. And I also have my uiimageviews on auto as well.
Right now the frame of the container scroll just crops off the inner content.
Any thoughts?
I ended up adding code to a function that allowed me to scale the interior of the scrollview the way I wanted.
[containerscrollView setFrame:CGRectMake(200.0f, 0.0f, 800.0f, 768.0f)];
containerscrollView.contentSize = CGSizeMake(800,containerscrollView.frame.size.height * scrollArrayCount);
for (UIScrollView *tmp in [containerscrollView subviews]) {
if (tmp.tag>4000) // make sure to only resize the inner scrollview {
[tmp setFrame:CGRectMake(tmp.frame.origin.x, tmp.frame.origin.y, 800.0f, 768.0f)];
_innerScrollView.contentSize =CGSizeMake(800.0f, 768.0f);
}
}
I´m trying to create a drop down menu that will display a set of controls. I got the animation working but the whole "button" moves with the animation.
My button is a UIView which is named settingsPanel, this is my code so far:
[UIView animateWithDuration:1.0f animations:^{
self.settingsPanel.bounds = CGRectMake(self.settingsPanel.bounds.origin.x, self.settingsPanel.bounds.origin.y, self.settingsPanel.bounds.size.width, self.settingsPanel.bounds.size.height + 300);
}];
I just want the height of the panel to change, and it does, but the whole view moves up a bit as well.
How can I create a animation that justs increases the height downwards?
You need to set the frame, not the bounds.
[UIView animateWithDuration:1.0f animations:^{
self.settingsPanel.frame =
CGRectMake(self.settingsPanel.frame.origin.x,
self.settingsPanel.frame.origin.y,
self.settingsPanel.frame.size.width,
self.settingsPanel.frame.size.height + 300);
}];
Frame is an external coordinate. When you change the frame, you change the actual position of the view within its superview, so you can keep the origin and width the same and just increase the height.
Bounds is an internal coordinate. When you change the bounds, the system has to decide what to do about the frame; its solution is that the change happens around a stationary center position. So the top moves upward as the height grows downward.