UIScrollView or UICollectionView to swipe through images in order called from firebase?

*爱你&永不变心* 提交于 2019-12-11 04:27:16

问题


My app is has a feature in which you answer questions about people you are following, such as (Option A, B, C, D are where the names for the users will be):

The idea is that you answer a question about a user and it randomly shuffles from the people you are following from the firebase database. The images are the profile pictures that a user uploads when signing up and they are shown in order from the top left, top right, bottom left, bottom right of whoever is in the answer of the question.

I am trying to use UIScrollView but all the images have stacked up on top of each other instead of being able to swipe between them (and the Question label has disappeared)

Is there a way to get the ScrollView to work or is there a better/more efficient way of integrating a UICollectionView (i've seen a few posts that recommend this for similar things)?

I'm new to this so would appreciate any help, thanks in advance :)


UPDATE:

I've edited the constraints so the left and right anchors of the image views should be correct and added a UIView on top of the UIScrollView on storyboard. I've also seen it could be done with UIPageViewController?

@IBOutlet weak var userImageScrollView: UIScrollView!
@IBOutlet weak var contentView: UIView!
@IBOutlet weak var questionLabel: UILabel!
@IBOutlet weak var optionA: UIButton!
@IBOutlet weak var optionB: UIButton!
@IBOutlet weak var optionC: UIButton!
@IBOutlet weak var optionD: UIButton!

func setupLayout() {
    userImageScrollView.isPagingEnabled = true
    userImageScrollView.isScrollEnabled = true

    userImageScrollView.addSubview(imageViewA)
    imageViewA.translatesAutoresizingMaskIntoConstraints = false
    imageViewA.widthAnchor.constraint(equalTo: userImageScrollView.widthAnchor).isActive = true
    imageViewA.heightAnchor.constraint(equalTo: userImageScrollView.heightAnchor).isActive = true
    imageViewA.topAnchor.constraint(equalTo: userImageScrollView.topAnchor).isActive = true
    imageViewA.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor).isActive = true
    imageViewA.leftAnchor.constraint(equalTo: userImageScrollView.leftAnchor)
    imageViewA.rightAnchor.constraint(equalTo: imageViewB.leftAnchor)
    imageViewA.contentMode = .scaleAspectFit

    userImageScrollView.addSubview(imageViewB)
    imageViewB.translatesAutoresizingMaskIntoConstraints = false
    imageViewB.widthAnchor.constraint(equalTo: userImageScrollView.widthAnchor).isActive = true
    imageViewB.heightAnchor.constraint(equalTo: userImageScrollView.heightAnchor).isActive = true
    imageViewB.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor).isActive = true
    imageViewB.leftAnchor.constraint(equalTo: imageViewA.rightAnchor)
    imageViewA.rightAnchor.constraint(equalTo: imageViewC.leftAnchor)
    imageViewB.contentMode = .scaleAspectFit

    userImageScrollView.addSubview(imageViewC)
    imageViewC.translatesAutoresizingMaskIntoConstraints = false
    imageViewC.widthAnchor.constraint(equalTo: userImageScrollView.widthAnchor).isActive = true
    imageViewC.heightAnchor.constraint(equalTo: userImageScrollView.heightAnchor).isActive = true
    imageViewC.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor).isActive = true
    imageViewC.leftAnchor.constraint(equalTo: imageViewB.rightAnchor)
    imageViewC.rightAnchor.constraint(equalTo: imageViewD.leftAnchor)
    imageViewC.contentMode = .scaleAspectFit

    userImageScrollView.addSubview(imageViewD)
    imageViewD.translatesAutoresizingMaskIntoConstraints = false
    imageViewD.widthAnchor.constraint(equalTo: userImageScrollView.widthAnchor).isActive = true
    imageViewD.heightAnchor.constraint(equalTo: userImageScrollView.heightAnchor).isActive = true
    imageViewD.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor).isActive = true
    imageViewD.leftAnchor.constraint(equalTo: imageViewC.rightAnchor)
    imageViewD.rightAnchor.constraint(equalTo: userImageScrollView.rightAnchor)
    imageViewD.contentMode = .scaleAspectFit

    self.userImageScrollView.delegate = self
}

回答1:


The reason your imageViews are on top of each other is you define:

 imageViewB.leftAnchor.constraint(equalTo: imageViewA.leftAnchor)

This translates to: the left of imageView B is the same as the left of imageViewA, essentially saying that their left sides both start at the same place, so they will be on top of each other.

So you need to define each item from left to right:

imageViewB.leftAnchor.constraint(equalTo: imageViewA.rightAnchor)

imageViewBs left side, starts on the right of imageViewA. imageView Cs leftAnchor would be equal to imageViewBs right and so on, until you reach the final imageViewD, where you would need to have the leftAnchor equal to imageViewCs rightAnchor AND imageViewDs rightAnchor equal to the scrollViews rightAnchor to allow scrolling to work correctly.

You could also do what you want easily with a scrollView if you want to scroll Down instead of left to right, instead of left and right anchors, use centerXAnchors to keep the views centered in the scrollView

You need to imagine you are describing the layout to someone, ImageViewA is at the top, so its top anchor is equal to the scrollViews top anchor.

With imageViewB you do the same describing it from the top down, so:

 imageViewB.topAnchor.constraint(equalTo: imageViewA.bottomAnchor).isActive = true

The top of image view B starts at the bottom of imageView A, then you do the same with the rest like so:

 imageViewC.topAnchor.constraint(equalTo: imageViewC.bottomAnchor).isActive = true

and

 imageViewD.topAnchor.constraint(equalTo: imageViewC.bottomAnchor).isActive = true

Because its a scrollView, and you are scrolling down, the top (imageViewA) needs to be set to the top of the scroll view, and additionally the bottom item needs to define its bottomAnchor to the bottom of the scrollView in order for scrolling to work correctly:

  imageViewD.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor).isActive = true 

You also are using centerXAnchor and leftAnchor together in some of the views, imagine the centerXAnchor is the same as leftAnchor but just describing it from a different part of the view, as your centerXAnchor comes after leftAnchor, it will just use the centerX, meaning that the image will be center in the scrollView.

I'd recommend following this pattern and building your constraints again from scratch, really focusing on what anchors need to be defined and where. You could also use the Interface Builder to add the views, but learning to define constraints like this will prove to be a very valuable skill in future and helps to keep your code very clear and clean.

UPDATE:

This code will do exactly what you want, take note of the height and width of the scroll view and the constants I use to give space. Each imageView is defined the way I stated above, left to right, with the last item having left and right constraints. remove your setupLayout and replace it with this (making sure to change the constraints where necessary to suit your app):

 func setupLayout() {
    view.addSubview(scrollView)
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 50).isActive = true
    scrollView.heightAnchor.constraint(equalToConstant: 300).isActive = true
    scrollView.widthAnchor.constraint(equalToConstant: 300).isActive = true
    scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    scrollView.backgroundColor = .gray
    scrollView.isPagingEnabled = true

    scrollView.addSubview(imageViewA)
    imageViewA.translatesAutoresizingMaskIntoConstraints = false

    imageViewA.widthAnchor.constraint(equalToConstant: 250).isActive = true
    imageViewA.heightAnchor.constraint(equalToConstant: 250).isActive = true

    imageViewA.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 25).isActive = true
    imageViewA.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 25).isActive = true

    imageViewA.backgroundColor = .cyan

    scrollView.addSubview(imageViewB)
    imageViewB.translatesAutoresizingMaskIntoConstraints = false

    imageViewB.heightAnchor.constraint(equalToConstant: 250).isActive = true
    imageViewB.widthAnchor.constraint(equalToConstant: 250).isActive = true


    imageViewB.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 25).isActive = true
    imageViewB.leftAnchor.constraint(equalTo: imageViewA.rightAnchor, constant: 25).isActive = true

    imageViewB.backgroundColor = .red

    scrollView.addSubview(imageViewC)
    imageViewC.translatesAutoresizingMaskIntoConstraints = false

    imageViewC.heightAnchor.constraint(equalToConstant: 250).isActive = true
    imageViewC.widthAnchor.constraint(equalToConstant: 250).isActive = true


    imageViewC.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 25).isActive = true
    imageViewC.leftAnchor.constraint(equalTo: imageViewB.rightAnchor, constant: 25).isActive = true

    imageViewC.backgroundColor = .black

    scrollView.addSubview(imageViewD)
    imageViewD.translatesAutoresizingMaskIntoConstraints = false

    imageViewD.heightAnchor.constraint(equalToConstant: 250).isActive = true
    imageViewD.widthAnchor.constraint(equalToConstant: 250).isActive = true


    imageViewD.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 25).isActive = true
    imageViewD.leftAnchor.constraint(equalTo: imageViewC.rightAnchor, constant: 25).isActive = true
    imageViewD.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: -25).isActive = true

    imageViewD.backgroundColor = .green


}

Here is a gif of what that code does:

via GIPHY

  • Don't forget to call setupLayout in viewDidLoad()

     override func viewDidLoad() {
    super.viewDidLoad()
    
    setupLayout()
    // Do any additional setup after loading the view, typically from a nib.
     }
    



回答2:


yes you can use CollectionView with pagingnation.just enable paging option of CollecitonView.

1.Add horizontal Collection View in your view's Top Area. Enable paging option from property Selector.

  1. Drag CollectionView cell into CollectionView. Resize cell to fill entire CollectionView
  2. add image to Cell

  3. setup delegate and datasource.

https://medium.com/@shaibalassiano/tutorial-horizontal-uicollectionview-with-paging-9421b479ee94



来源:https://stackoverflow.com/questions/54984711/uiscrollview-or-uicollectionview-to-swipe-through-images-in-order-called-from-fi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!