Skip to content

Instantly share code, notes, and snippets.

@SergLam
Last active February 6, 2023 14:32
Show Gist options
  • Save SergLam/cc6aab3af3d46270093b7d34f600203a to your computer and use it in GitHub Desktop.
Save SergLam/cc6aab3af3d46270093b7d34f600203a to your computer and use it in GitHub Desktop.
Scroll view constraints - programmaticaly + storyboard hack
// SnapKit(Masonry) 1
// https://github.com/SnapKit/Masonry
[self. addSubview: scrollView];
[scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(safeAreaLayoutGuide);
}];
[scrollView addSubview: contentView];
[contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(scrollView);
make.width.equalTo(scrollView);
make.height.equalTo(scrollView).priorityLow();
}];
// Pure autolayout
// https://monkey.work/blog/2020-11-08-uiscrollview/
// https://github.com/seifeet/SwiftFormScrolling
// https://useyourloaf.com/blog/easier-scrolling-with-layout-guides/
// VC Content view:
[self addSubview:scrollView];
scrollView.backgroundColor = UIColor.whiteColor;
scrollView.showsHorizontalScrollIndicator = YES;
scrollView.showsVerticalScrollIndicator = YES;
scrollView.isScrollEnabled = YES;
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[scrollView.topAnchor constraintEqualToAnchor: self.safeAreaLayoutGuide.topAnchor],
[scrollView.bottomAnchor constraintEqualToAnchor: self.safeAreaLayoutGuide.topAnchor],
[scrollView.leadingAnchor constraintEqualToAnchor: self.safeAreaLayoutGuide.leadingAnchor],
[scrollView.trailingAnchor constraintEqualToAnchor: self.safeAreaLayoutGuide.trailingAnchor]
]];
[scrollView addSubview:contentView];
contentView.backgroundColor = UIColor.whiteColor;
contentView.isUserInteractionEnabled = YES;
contentView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[contentView.topAnchor constraintEqualToAnchor: scrollView.contentLayoutGuide.topAnchor],
[contentView.bottomAnchor constraintEqualToAnchor: scrollView.contentLayoutGuide.bottomAnchor],
[contentView.leadingAnchor constraintEqualToAnchor: scrollView.contentLayoutGuide.leadingAnchor],
[contentView.trailingAnchor constraintEqualToAnchor: scrollView.contentLayoutGuide.trailingAnchor]
]];
NSLayoutConstraint* contentViewCenterY = [contentView.centerYAnchor constraintEqualToAnchor: scrollView.centerYAnchor];
contentViewCenterY.priority = UILayoutPriorityDefaultLow;
NSLayoutConstraint* contentViewHeight = [contentView.heightAnchor constraintGreaterThanOrEqualToAnchor: self.heightAnchor];
contentViewHeight.priority = UILayoutPriorityDefaultLow;
[NSLayoutConstraint activateConstraints:@[
[contentView.centerXAnchor constraintEqualToAnchor: scrollView.centerXAnchor],
contentViewCenterY,
contentViewHeight
]];
// Storyboard:
// Height - greater that or equal to 200
// Width - equat to safearea
// + MOST IMPORTANT: update content size at viewDidAppear (or any other method where all UI is ready)
CGSize scrollContentSize = CGSizeZero;
[UIView *] subviews = self.scrollView.subviews;
// scrollView?.contentSize = self.scrollView?.subviews.reduce(CGRect.zero) { $0.union($1.frame) }.size ?? .zero
scrollview.contentSize = scrollContentSize;
scrollView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, 20.0f, 0.0f);
[scrollView layoutSubviews];
-(void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
scrollView.contentSize = CGSizeMake(stackView.frame.width, stackView.frame.height);
}
// SnapKit:
// https://github.com/SnapKit/SnapKit
addSubview(scrollView)
scrollView.snp.makeConstraints { make in
make.edges.equalTo(safeAreaLayoutGuide.snp.edges)
}
scrollView.addSubview(contentView)
contentView.snp.makeConstraints { make in
make.edges.equalToSuperview()
make.width.equalToSuperview()
make.height.equalToSuperview().priority(.low)
}
// Pure autolayout
// https://monkey.work/blog/2020-11-08-uiscrollview/
// https://github.com/seifeet/SwiftFormScrolling
// VC Content view:
addSubview(scrollView)
scrollView.backgroundColor = UIColor.white
scrollView.showsHorizontalScrollIndicator = false
scrollView.showsVerticalScrollIndicator = true
scrollView.isScrollEnabled = true
scrollView.translatesAutoresizingMaskIntoConstraints = false
let scrollViewConstraints: [NSLayoutConstraint] = [
scrollView.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor)
]
NSLayoutConstraint.activate(scrollViewConstraints)
scrollView.addSubview(contentView)
contentView.backgroundColor = UIColor.white
contentView.isUserInteractionEnabled = true
contentView.translatesAutoresizingMaskIntoConstraints = false
let contentViewConstraints: [NSLayoutConstraint] = [
contentView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor)
]
NSLayoutConstraint.activate(contentViewConstraints)
let contentViewCenterY = contentView.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor)
contentViewCenterY.priority = .defaultLow
let contentViewHeight = contentView.heightAnchor.constraint(greaterThanOrEqualTo: self.heightAnchor)
contentViewHeight.priority = .defaultLow
NSLayoutConstraint.activate([
contentView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
contentViewCenterY,
contentViewHeight
])
// Storyboard:
// Height - greater that or equal to 200
// Width - equat to safearea
// + MOST IMPORTANT: update content size at viewDidAppear (or any other method where all UI is ready)
scrollView?.contentSize = self.scrollView?.subviews.reduce(CGRect.zero) { $0.union($1.frame) }.size ?? .zero
scrollView?.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)
scrollView?.layoutSubviews()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSize(width: stackView.frame.width, height: stackView.frame.height)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment