I'm trying to rebuild the twitter post tweet feature as well as the UI. I'm currently at the point that, when I type something long in the UITextView. My selected image that I want to tweet get bounds out of the container view that is in a scrollview.
See this example:
The blue background is the scrollview background and the grey background is the container views background. I can't scroll too.
My UIImageView has initially 0 height and is directly attached to the top of the textview.
I change the height of the UIImageView with their constraint:
// sets the image
let newHeight = self.postedImageView.getImageHeight(forImage: image)
self.postedImageViewHeightConstraint.constant = newHeight
self.view.layoutIfNeeded()
self.postedImageView.showImage(image)
How can I make this the scrollviews contentView height to grow as I type something in the textview so it doesn't get bounds out the view?
These are my constraints:
Update:
With the postedimageviews bottom constraint added to the content views bottom
Related
I have a UITableViewCell with a vertical UIStackView that currently has .alignment = fill and distribution = fill. Inside the stack view, I have a UILabel and a UIImageView.
The label should be left aligned and stretch across the width of the stackview (and it does). The image view has a content mode of aspect fit and should be centered in the middle of the stackview. I thought this was working as I wanted it to until I set a background color on the UIImageView and then realized that while the image itself appears correct (scaled and centered) the view itself stretches across the full width of the stackview (just like the label does).
Is it possible to have the label stretch the width of the stack view but not the image view? Ideally, I'd like the image view to just be the size of the scaled image and not stretch all the way to the edges of the stack view.
Make these changes:
Set your stack view's alignment to .center instead of .fill.
Constrain the label's width to equal the stack view's width.
In code, when you set the image view's image, also create an aspect-ratio constraint on the image view, like this:
class MyCell: UITableViewCell {
#IBOutlet private var myImageView: UIImageView!
private var imageViewAspectConstraint: NSLayoutConstraint?
func setImage(_ image: UIImage) {
myImageView.image = image
imageViewAspectConstraint?.isActive = false
imageViewAspectConstraint = myImageView.widthAnchor.constraint(
equalTo: myImageView.heightAnchor,
multiplier: image.size.width / image.size.height)
imageViewAspectConstraint!.isActive = true
}
}
Note that, since cells can be reused, you also have to remove a prior aspect-ratio constraint if there is one. The code I posted uses imageViewAspectConstraint to save the constraint and remove it when the image changes.
One approach:
calculate appropriate aspect-fit frame for your image
When the user taps on the image view, evaluate the tap position and only take action if the tap is within the aspect-fit frame.
Another approach:
calculate appropriate aspect-fit frame for your image
embed the UIImageView horizontally centered inside a UILayoutGuide
add the UILayoutGuide as the stack view's arranged subview
This will keep your label stretched across the width of the stack view (the cell) and center your image view, allowing you to detect the taps.
I have a UIScrollView for which I have a UIView which is the subview of the scroll view , the UIView has a lot of other subviews and I am getting the height for it dynamically after adding the subviews , this is my piece of code to add the view to scroll view
CGRect frameOfView = CGRectMake(0, 0,Get_Bounds.width, globalYPosition);
self.parentProductDetailView = [[UIView alloc]initWithFrame:frameOfView];
I am first initialising the view this way and then after adding all subviews I am doing this,
frameOfView.size.height = globalYPosition;
[self.parentProductDetailView layoutSubviews];
self.parentProductDetailView.frame = frameOfView;
[self.productDetailScrollView addSubview:self.parentProductDetailView];
self.productDetailScrollView.contentSize = CGSizeMake(0, self.parentProductDetailView.frame.size.height *1);
But my scrollview does not scroll properly it either sticks to top or bottom.
Here globalYPosition is the sum of height of all subviews added to parentProductDetailView
The procedure you used seems correct. No matter the subviews your scroll view should scroll properly by simply using a larger content size then its frame size.
The scroll view may stick, snap to some points if paging is enabled which is what is happening in your case. If the content view is larger then 1.5th of the frame size then the scroll view will snap to top/bottom or left/right. If it is smaller then it will only snap to starting position.
This may be very useful for situations like having a side menu that takes a part of a screen but in your case you should simply disable the paging and scrolling should work fine.
I have a ScrollView embedded in my ViewController. Inside the ScrollView I have embedded a content view (UIView) which has a UIImage set to match the left, top and right of the ScrollView with a dynamic height that changes depending on the aspect ratio of an image that the user can load after the ViewController loads. There are three buttons all horizontally aligned in the content view and spaced evenly apart from each other.
When the user loads in a photo that is too big for the screen it should just resize the ScrollView and the content view appropriately to allow scrolling to see the buttons but instead it just bunches up the buttons at the bottom of the screen.
Here is how the buttons should look:
Here is what happens when the photo is too big:
Here are the constraints of the ScrollView:
Here is my resizing code:
let img : UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage
let screenSize: CGRect = UIScreen.mainScreen().bounds
let multiplyNum = screenSize.width / img.size.width
imageViewHeightConstraint.constant = (multiplyNum*img.size.height)
imageView.image = img
Even when I try and change the ScrollViews height programatically to a very large number it still won't get any larger than the ViewController (no scrolling).
Constraints of ContentView:
Constraint of ImageView:
Constraints of first 2 buttons:
Constraints of last button:
Make sure to set all the constraints that completely define the vertical layout of all elements (top constraint for image, vertical space between elements and bottom constraint of last element), and try changing the priority of the content hugging or compression resistance of the elements.
Edit:
You can achieve that behaviour with this view hierarchy:
- UIView
- UIScrollView
- UIImage
- UIButton
- UIButton
- UIButton
There is no necessity to add a container view if you set the constraints like this:
scrollView:
Leading, trailing, top and bottom constraints to view (all 0)
inner views (horizontal):
Leading constraint from imageView to scrollView
Trailing constraint from imageView to scrollView
Equal width from imageView to view
inner views (vertical):
Top constraint from imageView to scrollView
Height constraint of imageView (this constraint constant will change depending on the size of the image)
Horizontal space from imageView to button1
Horizontal space from button1 to button2
Horizontal space from button2 to button3
Bottom constraint from button3 to scrollView
There is no necessity to change the priority of the content hugging or compression resistance of the elements.
I already check that it works in a project.
I made a simple test project to show the problem:
there is an imageview which is contained in scrollview
view -> scrollview -> imageview
scrollview's content size is same as imageview size = (AllWidth, AllHeight).
The problem is that if scrollview is scaled EXACTLY to fit image by width (scrollView.zoomScale = 320.0/AllWidth;) then calling zoomToRect
[scrollView zoomToRect:CGRectMake(0.0, 0.0, AllWidth, AllHeight) animated: NO];
does scroll imageview to the bottom for some reason. But nothing is expected to happen with UI
if scrollview is NOT scaled EXACTLY to fit image by width (scrollView.zoomScale = (320.0-1)/AllWidth;), then calling zoomToRect does what is expected - image is scaled and not scrolled to the bottom.
i noticed that in 'buggy' case ContentOffset.y is changed, but i have no any idea why.
to reproduce the issue, start new project, in viewcontroller.h file add <UIScrollViewDelegate>; viewcontroller.m is here: http://pastebin.com/bPUtuYn1 (in test project you will need double tap green image, then change "320.0-1" to "320.0" and try again)
I have a UIView which I need to stretch to the width of a UIScrollView. The problem is the next:
I'd need to stretch that UIView (which is EGOTableViewPullRefresh, just a custom UIView). In the view initialization I put [_refreshHeaderView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];. I tried:
-(void)scrollViewDidZoom:(UIScrollView *)scrollView {
NSLog(#"scrollViewDidZoom");
[_refreshHeaderView setFrame:CGRectMake(0.0f, 0.0f - webScroller.bounds.size.height, webScroller.frame.size.width, webScroller.bounds.size.height)];
}
But it just looks as the image. If I enter to a iOS designed page (such as Mobile Google), it looks ok:
How can I do that?
The size.width of a UIScrollView is width of the view on your device, not the width of the contents inside the scroll view (which would be scrollView.contentSize.width).
This means, if "your view" is outside the UIScrollView you do want the scroll view width, but if your view is inside the scroll view you need the content width.
Notice the bottom/Google screenshot you provided. Notice how there is no horizontal scrolling? In this case the scroll view contents size width is the same as the scroll view width so it works perfectly. The upper/stack overflow image does have a horizontal scroll bar though. So the content width of the scroll view is bigger than the scroll view width.
Short answer: Try setting your view to be the scrollView.contentSize.width, not scrollView.frame.size.width