1
votes

I try to use Xib files with UIScrollView. I set the constraints (top ,bottom ,leading ,trailing . equal width and height (priority 250)).

I added the xibs to view that inside of UIScrollView. And set the last element bottom anchor with greaterThanOrEqualTo .

But scrollview not scroll . Where is the problem ?

Thanks in advance.

@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var scrollViewSubView: UIView!

var campaignCollectionView:UICollectionView!
var pageControl:UIPageControl!
var winGiftVoucherCode:WinGiftVoucherView!
var lastCallDiscountView : LastCallDiscountView!

var lastCallDiscountView2 : LastCallDiscountView!
var lastCallDiscountView3 : LastCallDiscountView!

override func viewDidLoad() {
    super.viewDidLoad()

    setupNavigationBarItems()
    setCollectionView()
    setPageControl()
    winGiftVoucherCodeFunc()
    lastCallDiscountFunc()

    lastCallDiscountFunc2()
    lastCallDiscountFunc3()

}



func setCollectionView(){

    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .horizontal
    let cCV = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
    campaignCollectionView = cCV
    campaignCollectionView.translatesAutoresizingMaskIntoConstraints = false
    self.scrollViewSubView.addSubview(campaignCollectionView)

    campaignCollectionView.dataSource = self
    campaignCollectionView.delegate = self
    campaignCollectionView.backgroundColor = .white
    campaignCollectionView.isPagingEnabled = true
    campaignCollectionView.isScrollEnabled = true
    campaignCollectionView.showsHorizontalScrollIndicator = false

    if #available(iOS 11.0, *) {
        campaignCollectionView.topAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
    } else {
        campaignCollectionView.topAnchor.constraint(equalTo: self.scrollViewSubView.topAnchor, constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        campaignCollectionView.heightAnchor.constraint(equalToConstant: 150).isActive = true
        // campaignCollectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
    } else {
        campaignCollectionView.heightAnchor.constraint(equalToConstant: 150).isActive = true
        // campaignCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -10).isActive = true
    }

    if #available(iOS 11.0, *) {
        campaignCollectionView.leadingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.leadingAnchor, constant: 10).isActive = true
    } else {
        campaignCollectionView.leadingAnchor.constraint(equalTo: self.scrollViewSubView.leadingAnchor, constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        campaignCollectionView.trailingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true
    } else {
        campaignCollectionView.trailingAnchor.constraint(equalTo: self.scrollViewSubView.trailingAnchor, constant: -10).isActive = true
    }

    campaignCollectionView.register(UINib(nibName: "CampaignCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "CampaignCollectionViewCell")

}


func setPageControl(){
    let pC = UIPageControl()
    pageControl = pC
    pageControl.translatesAutoresizingMaskIntoConstraints = false
    self.scrollViewSubView.addSubview(pageControl)

    if #available(iOS 11.0, *) {
        pageControl.topAnchor.constraint(equalTo: campaignCollectionView.bottomAnchor , constant: 10).isActive = true
    } else {
        pageControl.topAnchor.constraint(equalTo: campaignCollectionView.bottomAnchor , constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        pageControl.heightAnchor.constraint(equalToConstant: 10).isActive = true
        // campaignCollectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
    } else {
        pageControl.heightAnchor.constraint(equalToConstant: 10).isActive = true
        // campaignCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -10).isActive = true
    }

    if #available(iOS 11.0, *) {
        pageControl.leadingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.leadingAnchor, constant: 10).isActive = true
    } else {
        pageControl.leadingAnchor.constraint(equalTo: self.scrollViewSubView.leadingAnchor, constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        pageControl.trailingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true
    } else {
        pageControl.trailingAnchor.constraint(equalTo: self.scrollViewSubView.trailingAnchor, constant: -10).isActive = true
    }

    //pageControl.backgroundColor = .black
    //pageControl.tintColor = .white
    pageControl.pageIndicatorTintColor = .lightGray
    pageControl.currentPageIndicatorTintColor = .black

    pageControl.numberOfPages = 3
    pageControl.currentPage = 0
    //pageControl.hidesForSinglePage = true
}

func winGiftVoucherCodeFunc(){

    let wGVC : WinGiftVoucherView = UIView.fromNib()
    winGiftVoucherCode = wGVC
    winGiftVoucherCode.translatesAutoresizingMaskIntoConstraints = false
    self.scrollViewSubView.addSubview(winGiftVoucherCode)

    if #available(iOS 11.0, *) {
        winGiftVoucherCode.topAnchor.constraint(equalTo: pageControl.bottomAnchor , constant: 10).isActive = true
    } else {
        winGiftVoucherCode.topAnchor.constraint(equalTo: pageControl.bottomAnchor , constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        winGiftVoucherCode.heightAnchor.constraint(equalToConstant: 150).isActive = true
        // campaignCollectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
    } else {
        winGiftVoucherCode.heightAnchor.constraint(equalToConstant: 150).isActive = true
        // campaignCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -10).isActive = true
    }

    if #available(iOS 11.0, *) {
        winGiftVoucherCode.leadingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.leadingAnchor, constant: 10).isActive = true
    } else {
        winGiftVoucherCode.leadingAnchor.constraint(equalTo: self.scrollViewSubView.leadingAnchor, constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        winGiftVoucherCode.trailingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true
    } else {
        winGiftVoucherCode.trailingAnchor.constraint(equalTo: self.scrollViewSubView.trailingAnchor, constant: -10).isActive = true
    }

    let rate : CGFloat = 0.85

    let mainRect = winGiftVoucherCode.frame
    let rec = winGiftVoucherCode.progressX.frame
    let aa = ProgressView(frame: CGRect(x: 0, y: 0, width: ( mainRect.size.width - 100 ) * rate , height: rec.size.height) )
    aa.backgroundColor = UIColor.black
    self.winGiftVoucherCode.progressX.addSubview(aa)

    winGiftVoucherCode.voucherRemainderViewLeftConstraint.constant = ( winGiftVoucherCode.frame.width - 100 ) * rate - 20


}

func lastCallDiscountFunc(){

    let lCDV : LastCallDiscountView = UIView.fromNib()
    lastCallDiscountView = lCDV
    lastCallDiscountView.translatesAutoresizingMaskIntoConstraints = false
    self.scrollViewSubView.addSubview(lastCallDiscountView)

    if #available(iOS 11.0, *) {
        lastCallDiscountView.topAnchor.constraint(equalTo: winGiftVoucherCode.bottomAnchor , constant: 10).isActive = true
    } else {
        lastCallDiscountView.topAnchor.constraint(equalTo: winGiftVoucherCode.bottomAnchor , constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        lastCallDiscountView.heightAnchor.constraint(equalToConstant: 150).isActive = true
        // campaignCollectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
    } else {
        lastCallDiscountView.heightAnchor.constraint(equalToConstant: 150).isActive = true
        // campaignCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -10).isActive = true
    }

    if #available(iOS 11.0, *) {
        lastCallDiscountView.leadingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.leadingAnchor, constant: 10).isActive = true
    } else {
        lastCallDiscountView.leadingAnchor.constraint(equalTo: self.scrollViewSubView.leadingAnchor, constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        lastCallDiscountView.trailingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true
    } else {
        lastCallDiscountView.trailingAnchor.constraint(equalTo: self.scrollViewSubView.trailingAnchor, constant: -10).isActive = true
    }

}

func lastCallDiscountFunc2(){

    let lCDV : LastCallDiscountView = UIView.fromNib()
    lastCallDiscountView2 = lCDV
    lastCallDiscountView2.translatesAutoresizingMaskIntoConstraints = false
    self.scrollViewSubView.addSubview(lastCallDiscountView2)

    if #available(iOS 11.0, *) {
        lastCallDiscountView2.topAnchor.constraint(equalTo: lastCallDiscountView.bottomAnchor , constant: 10).isActive = true
    } else {
        lastCallDiscountView2.topAnchor.constraint(equalTo: lastCallDiscountView.bottomAnchor , constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        lastCallDiscountView2.heightAnchor.constraint(equalToConstant: 150).isActive = true
        // campaignCollectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
    } else {
        lastCallDiscountView2.heightAnchor.constraint(equalToConstant: 150).isActive = true
        // campaignCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -10).isActive = true
    }

    if #available(iOS 11.0, *) {
        lastCallDiscountView2.leadingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.leadingAnchor, constant: 10).isActive = true
    } else {
        lastCallDiscountView2.leadingAnchor.constraint(equalTo: self.scrollViewSubView.leadingAnchor, constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        lastCallDiscountView2.trailingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true
    } else {
        lastCallDiscountView2.trailingAnchor.constraint(equalTo: self.scrollViewSubView.trailingAnchor, constant: -10).isActive = true
    }

}

func lastCallDiscountFunc3(){

    let lCDV : LastCallDiscountView = UIView.fromNib()
    lastCallDiscountView3 = lCDV
    lastCallDiscountView3.translatesAutoresizingMaskIntoConstraints = false
    self.scrollViewSubView.addSubview(lastCallDiscountView3)

    if #available(iOS 11.0, *) {
        lastCallDiscountView3.topAnchor.constraint(equalTo: lastCallDiscountView2.bottomAnchor , constant: 10).isActive = true
    } else {
        lastCallDiscountView3.topAnchor.constraint(equalTo: lastCallDiscountView2.bottomAnchor , constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        lastCallDiscountView3.heightAnchor.constraint(equalToConstant: 150).isActive = true
    } else {
        lastCallDiscountView3.heightAnchor.constraint(equalToConstant: 150).isActive = true
    }

    if #available(iOS 11.0, *) {
        lastCallDiscountView3.leadingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.leadingAnchor, constant: 10).isActive = true
    } else {
        lastCallDiscountView3.leadingAnchor.constraint(equalTo: self.scrollViewSubView.leadingAnchor, constant: 10).isActive = true
    }

    if #available(iOS 11.0, *) {
        lastCallDiscountView3.trailingAnchor.constraint(equalTo: scrollViewSubView.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true
    } else {
        lastCallDiscountView3.trailingAnchor.constraint(equalTo: self.scrollViewSubView.trailingAnchor, constant: -10).isActive = true
    }

    if #available(iOS 11.0, *) {
        lastCallDiscountView3.bottomAnchor.constraint(greaterThanOrEqualTo: self.scrollViewSubView.safeAreaLayoutGuide.bottomAnchor, constant: 10).isActive = true
    } else {
        lastCallDiscountView3.bottomAnchor.constraint(greaterThanOrEqualTo: self.scrollViewSubView.bottomAnchor, constant: 10).isActive = true
    }

}
1

1 Answers

1
votes

Firstly, I strongly urge you to set up all your UI in XIBs/storyboards. It's so much easier to see what you're doing, rather than adding views programmatically.

If a scroll view doesn't scroll it probably means that its contentSize is smaller than its frame. It could also mean that you're blocking touches to it, which may be caused by your UICollectionView. Embedding a scrollable view inside a scrollable view will cause you headaches.

If you want to properly set up scroll views using autolayout I recommend following this article. The core principle is:

  1. Add the scroll view to the VC's view and set its constraints to match the edges (leading/trailing/top/bottom) of the safe area.
  2. Add a content view (UIView) whose constraints match the edges of the scroll view.
  3. Set the content view's width to match the safeArea's width (assuming you want vertical scrolling, otherwise match the heights).
  4. Add all your views to the content view and ensure that their constraints provide it with a fixed height (again, assuming you're going for vertical scrolling). That means having at least 1 view with a constraint to the top of the content view, and at least 1 with a constraint to its bottom, with set heights and vertical spaces in between.

It takes a while to learn how to do this properly, so be patient.