Reputation: 33
I am trying to acheve a behavior where i have a form in a table view with a minimum width. So basically, if the screen i wide, the view only scrolls vertically but when the screen is narrow, the form shrinks to its minimum width and then starts to scroll horizontally as to not loose content. So, I need to use autoLayout to set up these constraints and I want to do it programatically (because of frameworks I'm using).
The problem is, I can't get my view to scroll horizontally AT ALL. I have read all I could find about it, and tried everything I could think of, nothing works. Right now I try to just add a large picture to my view and make it scroll both directions, but I can't make it work.
This is my hierarchy:
>UIView
>>UIScrollView
>>>ContentView (UIView)
>>>>ImageView
And this is my code:
override func viewDidLoad() {
if scrollView == nil {
scrollView = UIScrollView(frame: view.bounds)
scrollView.backgroundColor = .groupTableViewBackground
scrollView.isDirectionalLockEnabled = true
scrollView.showsHorizontalScrollIndicator = true
}
if scrollView.superview == nil {
view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
let contentView = UIView(frame: view.bounds)
scrollView.addSubview(contentView)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
let a = contentView.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
let b = contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
a.priority = .defaultLow
b.priority = .defaultLow
a.isActive = true
b.isActive = true
let image = MyImage.icon(named: "myImage", of: CGSize(width: 1000, height: 1000))
let imageView = UIImageView(image: image)
imageView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(imageView)
imageView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
}
super.viewDidLoad()
}
When I debug the view hirearchy, I can see that the size of the image is still correct (1000, 1000)
but the content size of the scrollView isn't updated and the picture is truncated, with no scroll.
<UIScrollView: 0x11ead5c00; frame = (0 0; 834 1112); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x1c8853800>; layer = <CALayer: 0x1c8c32240>; contentOffset: {0, -64}; contentSize: {834, 1112}; adjustedContentInset: {64, 0, 0, 0}>
<UIImageView: 0x11a89b000; frame = (0 0; 1000 1000); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1c8231c80>>
I found and looked at this example to setup a scrolling view programatically https://github.com/zaxonus/AutoLayScroll. It scrolls vertically, but for this either, I can't for my life set it up to scroll horizontally.
Please help, what am I overlooking?
Upvotes: 2
Views: 188
Reputation: 33
Thanks to Anton, I got it working! I just thougt i'd share my final solution if anyone else is trying to do what I wanted.
With the below code you can add horizontal scroll functionality to the forms of the Eureka frameworks FormViewController (https://github.com/xmartlabs/Eureka).
import UIKit
import Eureka
class MyScrollableViewController: FormViewController {
var scrollView: UIScrollView!
var minimumWidth: CGFloat = 500.0
override func viewDidLoad() {
if tableView == nil {
tableView = UITableView(frame: view.bounds, style: .grouped)
if #available(iOS 9.0, *) {
tableView.cellLayoutMarginsFollowReadableWidth = false
}
}
if scrollView == nil {
scrollView = UIScrollView(frame: view.bounds)
scrollView.backgroundColor = .groupTableViewBackground
scrollView.isDirectionalLockEnabled = true
scrollView.showsHorizontalScrollIndicator = true
}
if scrollView.superview == nil && tableView.superview == nil {
view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
let contentView = UIView(frame: view.bounds)
scrollView.addSubview(contentView)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
let a = contentView.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
let b = contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
a.priority = .defaultLow
b.priority = .defaultLow
a.isActive = true
b.isActive = true
contentView.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
tableView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
tableView.widthAnchor.constraint(greaterThanOrEqualToConstant: minimumWidth).isActive = true
}
// Has to be called after setting up the tableView since we override the Eureka default setup
super.viewDidLoad()
// Setup your Eureka form as usual
form +++ Section()
<<< LabelRow { row in
row.title = "My first row"
}
}
}
Upvotes: 0
Reputation: 1675
To make your example scrollView
content size be 1000x1000 just add these constraints to imageView
:
imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
Without them your contentView
doesn't know it should wrap imageView
so its' size is calculated according to low priority constraints a
and b
Upvotes: 1