I want to make something like article to read view controller that contains UIImage and Label nested in the scroll view.
I want if the article content is not to big, the scrolling function is disabled, but if the content is big, I want it can be scrolled and it can be scrolled as the same height of the label content height.
(if the content article is not too much, then i don't need to scroll)
but if the content is a lot then I expect that I can scroll. at the moment, I can scroll if the content is big like below
I have tried to set the bottom anchor like my code below but it doesn't work. here is the autolayout I use for the bottom label contraint andthe view hierarchy
class NotificationDetailVC: UIViewController {
#IBOutlet weak var notificationTitleLabel: UILabel!
#IBOutlet weak var notificationImage: UIImageView!
#IBOutlet weak var notificationDateLabel: UILabel!
#IBOutlet weak var notificationScrollView: UIScrollView!
#IBOutlet weak var notificationContentLabel: UILabel!
var dataNotification : [String:Any]?
override func viewDidLoad() {
super.viewDidLoad()
notificationScrollView.contentLayoutGuide.bottomAnchor.constraint(equalTo: notificationContentLabel.bottomAnchor).isActive = true
}
}
Don't make bottom constraint to greater than. just set it equal to.
Scroll view has a content view which contains all scrollable view. You have to set height, width and x,y position of content view.
Set top, bottom, leading and trailing constraint to content view.
Scrollview's scrolling directions depands on height and width of contantview. if you set content view's width equal to scrollview than scrollview is not scrollable in horizontal direction. Same for height , if you set content view's height equal to scrollview's height than scrollview is not scrollable in vertical direction.
In your case you have to set content view's width equal to scrollview's width therefore scrollview is not scrollable in horizontal direction. Content view automatically get height according to subviews(In your case UIimageview and uilabel). so set height, top, bottom constraint of imageview and top and bottom constraints of uilabel because uilabel height automatically set by it's text. Set number of line = 0 in UILabel.
Set Label bottom constaint equal to any constant height (say 20) & number of lines = 0.
as you are using scrollview then you have to give height to the imageview. You don't need to worry about label height bcz its heigght will be calculated by its content height.
Now your scrollviewContentHeight = imgView.height + all labels content height. Make sure each component (imageview & every label) have top and bottom constraint.
That's all you have to do.
Related
I have the following layout:
UIImageView
UIView (with UILabel)
UITableView
As the tableView is scrolled up, the height of the imageView is decreased before actually scrolling the tableView. The following code is used for that:
let headerImageViewMaxHeight: CGFloat = 200
let headerImageViewMinHeight: CGFloat = UIApplication.shared.statusBarFrame.height
#IBOutlet var headerImageViewHeightConstraint: NSLayoutConstraint!
#IBOutlet var headerImageView: UIImageView!
#IBOutlet var subtitleView: UIView!
#IBOutlet var subtitleLabel: TextLabel!
private var contentOffsetDictionary: NSMutableDictionary!
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.isKind(of: UICollectionView.self) {
let horizontalOffset: CGFloat = scrollView.contentOffset.x
let collectionView: UICollectionView = scrollView as! UICollectionView
contentOffsetDictionary.setValue(horizontalOffset, forKey: collectionView.tag.description)
} else if scrollView == tableView {
let y: CGFloat = scrollView.contentOffset.y
let newHeaderImageViewHeight: CGFloat = headerImageViewHeightConstraint.constant - y
if newHeaderImageViewHeight > headerImageViewMaxHeight {
headerImageViewHeightConstraint.constant = headerImageViewMaxHeight
} else if newHeaderImageViewHeight < headerImageViewMinHeight {
headerImageViewHeightConstraint.constant = headerImageViewMinHeight
} else {
headerImageViewHeightConstraint.constant = newHeaderImageViewHeight
scrollView.contentOffset.y = 0
}
}
}
The following two images shown the current states of scrolled down or up:
Scrolled down (initial state).
Scrolled up.
As you can see, initially the grey bar saying To Table -> Table 1 is scrolled down and is about 60 high.
When it's scrolled up, it scrolles until the safeArea. What I want to achieve is that once it reaches the safe area, it continues scrolling up into the safeArea (top notch), while keeping the text in exactly the same place (topSpace to safeArea of the text should stay the same). So, basically growing the UIView to go into the safeArea.
This image shows the ViewController layout.
Header View can be ignored, as that is aligned to the top of the viewController, but no constraints to anything else than superView.
TopSpace of the view in question, is 0 to the UIImageView.
Changing headerImageViewMinHeight to 0, makes it scroll up to the actual top of the screen, without expanding it. So this seems like a good start, but needs some extra logic or constraints.
As the UIView doesn't have a specific height constraint, changing its UILabel's top space from = 16 to => 16, there's the warning of missing Y constraint or height.
Otherwise that, together with UILabel's top space to the viewController's safeArea of => 8 sounds like it could work.
Any ideas are welcome.
EDIT: The following picture basically shows what I want, except that here the UILabel's top is not aligned to the safe area.
What this picture shows is achieved by changing headerImageViewMinHeight to 0.
Add constriant
Uncheck constraint to margin
double click on Align bottom/ Align top
click on last baseline (for bottom)/ first baseline (for top constrraint)
DONE
Adding proportional fill setting in a UIStackview won't let the view stretch properly. Is this the expected behaviour?
Fill proportionally' distribution type works with intrinsic content size.
So if our vertical stack(height say 600) view has 2 views, ViewA (intrinsic content height 200) and ViewB(intrinsic content height 100), the stack view will size them to ViewA(height 400) and ViewB(height 200).
Here in IB what you see is not what you get.
Dragging to make frames change is useless. Just run the app.
You will see the expected behaviour only when the child views somehow get the intrinsic/constrained height.
How it looks in IB Here the top stack view has views constrained to be of height minimum 10 and 30, i.e. ration 1:4.
What we really get
Top stack view is what we had expected to look like. View with height in ratio 1:4. And bottom one with ratio 1:1, not expected.
You can fix this by creating a custom view
class CustomHeightView: UIView {
var height = 1.0
override public var intrinsicContentSize: CGSize {
return CGSize(width: 0.0, height: height)
}
}
Change the class of your UIView to CustomHeightView
So in the Controller create an outlet for the UIViews
#IBOutlet weak var header_one: CustomHeightView!
#IBOutlet weak var header_two: CustomHeightView!
Then in your viewDidLoad set the proportion the way you want it
override func viewDidLoad() {
super.viewDidLoad()
header_one.height = 1.8
header_two.height = 1.2
}
I have this situation :
When I tap on "add" button I reduce the pink view's(first view) height and I execute this code:
#IBOutlet weak var viewPink: UIView!
#IBAction func add(_ sender: AnyObject) {
viewPink.frame = CGRect(x: viewPink.frame.origin.x, y: viewPink.frame.origin.y, width: viewPink.frame.size.width, height: viewPink.frame.size.height - 50)
}
but I want that the last view remains to the same distance from the pink view , essentially you have to climb on why the pink view reduces its height , instead the second view remains where it was before.
Can you help me about it?
P.S I set the vertical spacing constraint between the two views but It doesn't work
You should add an Height constraint on your pink view, create an IBOutlet to this constraint in your ViewController, and set the "constant" property to change the height.
Example:
heightConstraint.constant = 150
This will change the height with Autolayout, you shouldn't change the height by setting a new frame because it doesn't use Autolayout.
I have a superview with another subview inside of it. The subview has constraints set to it to be centered in the superview and half the size of the superview.
The position and size of the superview are being changed when a button is clicked, but the position and size of the subview is not being changed with it. I tried using UIView.updateConstraints(), but it is not repositioning it or resizing it.
So my question is:
What would be the best way to resize and reposition the subview with respect to the superview?
Thank you!
Here is the code:
func updateTimerFormat() {
minutesContainer.frame.size.width *= 0.75
minutesContainer.frame.size.height *= 0.75
minutesContainer.center.x = view.center.x
minutesContainer.center.y = view.center.y * 1.5 - 30
// The minutes label is the subview of the minutesContainer
minutesLabel.updateConstraints()
}
You should not to call updateConstraints(), because I do not think your view's constraints need to be updated.
You just need to change SuperView's size or position. Then your view can automatically set the size and position, because you set their constraints before.
This is a demo.https://github.com/cythb/iOSIssues/tree/master/2_AjustSizeDemo
Constraint subview(yellow) center to superview(green) center. Constraint size is half of the superview(green).
When you click button, you don't do anything else,just change the size of superview.
There are two ways-
Implement the func layoutSubviews(). This method is called when super view frame become change. In this method you can change your subviews frame.
Second option is that use autolayout during configure the subviews
1/ Connect minutesContainer constraints to your ViewController:
#IBOutlet weak var widthConstraint: NSLayoutConstraint!
#IBOutlet weak var heightConstraint: NSLayoutConstraint!
#IBOutlet weak var centerYConstraint: NSLayoutConstraint!
2/ Change your updateTimerFormat method:
func updateTimerFormat() {
widthConstraint.constant *= 0.75
heightConstraint.constant *= 0.75
centerYConstraint.constant = view.center.y * 0.5 - 30
}
I am using swift to get my scrollview going the structure of my elements is as shown
The code that i am using in my view controller is
import UIKit
class scrollview: UIViewController {
#IBOutlet weak var scroller: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
scroller.userInteractionEnabled=true
scroller.contentSize=CGSizeMake(scroller.frame.size.width, scroller.frame.size.height)
But i am not able to make my page scroll can anyone help me out with this am i missing any constrains or something wrong with my code?
scroller.contentSize=CGSizeMake(should be total width of the labels not scroll view width, should be total height of the labels not scrollview height)
contentsize should be greater than frame size for scrolling.
In order for UIScrollView to scroll, the content size must be greater than its frame size. If, for example, you want to scroll vertically, it has to be true that scrollView.contentSize.height > scrollView.frame.size.height.