Reputation: 153
I currently have a UIScrollView with a UIImageView (top image) positioned below the UINavigationBar. However, I want to position the UIImageView at the very top of the screen (bottom image). Is there a way to implement this?
What I've tried so far: I added a UIScrollView extension (source) that is supposed to scroll down to the view parameter provided, but it hasn't worked for me.
extension UIScrollView {
// Scroll to a specific view so that it's top is at the top our scrollview
func scrollToView(view:UIView, animated: Bool) {
if let origin = view.superview {
// Get the Y position of your child view
let childStartPoint = origin.convert(view.frame.origin, to: self)
// Scroll to a rectangle starting at the Y of your subview, with a height of the scrollview
self.scrollRectToVisible(CGRect(x:0, y:childStartPoint.y,width: 1,height: self.frame.height), animated: animated)
}
}
// Bonus: Scroll to top
func scrollToTop(animated: Bool) {
let topOffset = CGPoint(x: 0, y: -contentInset.top)
setContentOffset(topOffset, animated: animated)
}
// Bonus: Scroll to bottom
func scrollToBottom() {
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
if(bottomOffset.y > 0) {
setContentOffset(bottomOffset, animated: true)
}
}
}
class MealDetailsVC: UIViewController {
private var mealInfo: MealInfo
init(mealInfo: MealInfo) {
self.mealInfo = mealInfo
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
scrollView.scrollToView(view: iv, animated: false) // used extension from above
}
lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
return scrollView
}()
lazy var iv: UIImageView = {
let iv = UIImageView()
iv.image = Image.defaultMealImage!
iv.contentMode = .scaleAspectFill
return iv
}()
}
extension MealDetailsVC {
func setupViews() {
addBackButton()
addSubviews()
autoLayoutViews()
constrainSubviews()
}
fileprivate func addBackButton() {
...
}
@objc func goBack(sender: UIBarButtonItem) {
...
}
fileprivate func addSubviews() {
view.addSubview(scrollView)
scrollView.addSubview(iv)
}
fileprivate func autoLayoutViews() {
scrollView.translatesAutoresizingMaskIntoConstraints = false
iv.translatesAutoresizingMaskIntoConstraints = false
}
fileprivate func constrainSubviews() {
NSLayoutConstraint.activate([
scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor),
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
NSLayoutConstraint.activate([
iv.topAnchor.constraint(equalTo: scrollView.topAnchor),
iv.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
iv.heightAnchor.constraint(equalTo: iv.widthAnchor, multiplier: 0.6)
])
}
}
Upvotes: 0
Views: 793
Reputation: 1041
This may help.
scrollView.contentInsetAdjustmentBehavior = .never
For more information,
This property specifies how the safe area insets are used to modify the content area of the scroll view. The default value of this property is UIScrollViewContentInsetAdjustmentAutomatic.
Upvotes: 1
Reputation: 590
Don't set a height anchor and add a imageView centerXAnchor
equal to ScrollView centerXAnchor
constraint. set imageView.contentMode to .scaleAspectFit
Upvotes: 0