I currently have a UIScrollView with a UIImageView (top image) that is positioned below the UINavigationBar. However, I want to position the UIImageView to be 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 (
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)
])
}
}
CodePudding user response:
Don't set a height anchor and add a imageView centerXAnchor
equal to ScrollView centerXAnchor
constraint. set imageView.contentMode to .scaleAspectFit
CodePudding user response:
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.