UIScrollView 或 UICollectionView 按从 firebase 调用的顺序滑动图像?
UIScrollView or UICollectionView to swipe through images in order called from firebase?
我的应用程序有一个功能,您可以在其中回答有关您关注的人的问题,例如(选项 A、B、C、D 是用户姓名所在的位置):
这个想法是你回答一个关于用户的问题,然后它从你从 firebase 数据库中关注的人中随机洗牌。这些图片是用户在注册时上传的个人资料图片,它们按照从左上角、右上角、左下角、右下角的顺序显示在问题的答案中。
我正在尝试使用 UIScrollView,但所有图像都堆叠在一起,无法在它们之间滑动(并且问题标签已消失)
有没有办法让 ScrollView 工作,或者有没有 better/more 集成 UICollectionView 的有效方法(我看到一些帖子推荐这个用于类似的事情)?
我是新手,非常感谢任何帮助,在此先感谢:)
更新:
我编辑了约束,使图像视图的左右锚点应该正确,并在故事板上的 UIScrollView 顶部添加了一个 UIView。我还看到它可以用 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
}
是的,您可以使用 CollectionView 并 pagingnation.just 启用 CollecitonView 的分页选项。
1.Add 水平 Collection 在您视图的顶部区域中查看。启用分页选项
来自 属性 选择器。
- 将 CollectionView 单元格拖到 CollectionView 中。调整单元格大小以填充
整个 Collection查看
将图像添加到单元格
设置委托和数据源。
https://medium.com/@shaibalassiano/tutorial-horizontal-uicollectionview-with-paging-9421b479ee94
您的 imageView 彼此重叠的原因是您定义的:
imageViewB.leftAnchor.constraint(equalTo: imageViewA.leftAnchor)
这意味着:imageView B 的左侧与 imageViewA 的左侧相同,本质上是说它们的左侧都从同一位置开始,因此它们将彼此重叠。
因此您需要从左到右定义每个项目:
imageViewB.leftAnchor.constraint(equalTo: imageViewA.rightAnchor)
imageViewBs 左侧,从 imageViewA 右侧开始。 imageView Cs leftAnchor 将等于 imageViewBs right 等等,直到到达最终的 imageViewD,您需要让 leftAnchor 等于 imageViewCs rightAnchor 和 imageViewDs rightAnchor 等于 scrollViews rightAnchor 以允许滚动正常工作。
如果您想向下滚动而不是从左向右滚动而不是左右锚点,您也可以使用 scrollView 轻松地做您想做的事情,使用 centerXAnchors
使视图在 scrollView
你需要想象你正在向某人描述布局,ImageViewA 在顶部,所以它的顶部锚点等于 scrollViews 顶部锚点。
对于 imageViewB,您可以从上到下进行相同的描述,因此:
imageViewB.topAnchor.constraint(equalTo: imageViewA.bottomAnchor).isActive = true
图像视图 B 的顶部从图像视图 A 的底部开始,然后您对其余部分执行相同操作,如下所示:
imageViewC.topAnchor.constraint(equalTo: imageViewC.bottomAnchor).isActive = true
和
imageViewD.topAnchor.constraint(equalTo: imageViewC.bottomAnchor).isActive = true
因为它是一个scrollView,而你是向下滚动的,top(imageViewA)需要设置到scroll view的顶部,另外bottom item需要定义它的bottomAnchor到scrollView的底部滚动正确工作的顺序:
imageViewD.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor).isActive = true
您还在某些视图中同时使用 centerXAnchor
和 leftAnchor
,假设 centerXAnchor
与 leftAnchor
相同,只是从不同的角度描述它视图的一部分,因为您的 centerXAnchor
在 leftAnchor 之后,它将只使用 centerX,这意味着图像将在 scrollView 中居中。
我建议遵循此模式并从头开始重新构建您的约束,真正关注需要定义的锚点和位置。您也可以使用 Interface Builder 来添加视图,但是学习像这样定义约束将在未来被证明是一项非常有价值的技能,并且有助于保持您的代码非常清晰和干净。
更新:
此代码将完全按照您的要求执行,请注意滚动视图的高度和宽度以及我用来提供 space 的常量。每个 imageView 都按照我上面所说的方式定义,从左到右,最后一个项目具有左右约束。删除您的 setupLayout 并将其替换为这个(确保在必要时更改约束以适合您的应用程序):
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
}
这是该代码的作用的 gif:
别忘了在viewDidLoad()
中调用setupLayout
override func viewDidLoad() {
super.viewDidLoad()
setupLayout()
// Do any additional setup after loading the view, typically from a nib.
}
我的应用程序有一个功能,您可以在其中回答有关您关注的人的问题,例如(选项 A、B、C、D 是用户姓名所在的位置):
这个想法是你回答一个关于用户的问题,然后它从你从 firebase 数据库中关注的人中随机洗牌。这些图片是用户在注册时上传的个人资料图片,它们按照从左上角、右上角、左下角、右下角的顺序显示在问题的答案中。
我正在尝试使用 UIScrollView,但所有图像都堆叠在一起,无法在它们之间滑动(并且问题标签已消失)
有没有办法让 ScrollView 工作,或者有没有 better/more 集成 UICollectionView 的有效方法(我看到一些帖子推荐这个用于类似的事情)?
我是新手,非常感谢任何帮助,在此先感谢:)
更新:
我编辑了约束,使图像视图的左右锚点应该正确,并在故事板上的 UIScrollView 顶部添加了一个 UIView。我还看到它可以用 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
}
是的,您可以使用 CollectionView 并 pagingnation.just 启用 CollecitonView 的分页选项。
1.Add 水平 Collection 在您视图的顶部区域中查看。启用分页选项 来自 属性 选择器。
- 将 CollectionView 单元格拖到 CollectionView 中。调整单元格大小以填充 整个 Collection查看
将图像添加到单元格
设置委托和数据源。
https://medium.com/@shaibalassiano/tutorial-horizontal-uicollectionview-with-paging-9421b479ee94
您的 imageView 彼此重叠的原因是您定义的:
imageViewB.leftAnchor.constraint(equalTo: imageViewA.leftAnchor)
这意味着:imageView B 的左侧与 imageViewA 的左侧相同,本质上是说它们的左侧都从同一位置开始,因此它们将彼此重叠。
因此您需要从左到右定义每个项目:
imageViewB.leftAnchor.constraint(equalTo: imageViewA.rightAnchor)
imageViewBs 左侧,从 imageViewA 右侧开始。 imageView Cs leftAnchor 将等于 imageViewBs right 等等,直到到达最终的 imageViewD,您需要让 leftAnchor 等于 imageViewCs rightAnchor 和 imageViewDs rightAnchor 等于 scrollViews rightAnchor 以允许滚动正常工作。
如果您想向下滚动而不是从左向右滚动而不是左右锚点,您也可以使用 scrollView 轻松地做您想做的事情,使用 centerXAnchors
使视图在 scrollView
你需要想象你正在向某人描述布局,ImageViewA 在顶部,所以它的顶部锚点等于 scrollViews 顶部锚点。
对于 imageViewB,您可以从上到下进行相同的描述,因此:
imageViewB.topAnchor.constraint(equalTo: imageViewA.bottomAnchor).isActive = true
图像视图 B 的顶部从图像视图 A 的底部开始,然后您对其余部分执行相同操作,如下所示:
imageViewC.topAnchor.constraint(equalTo: imageViewC.bottomAnchor).isActive = true
和
imageViewD.topAnchor.constraint(equalTo: imageViewC.bottomAnchor).isActive = true
因为它是一个scrollView,而你是向下滚动的,top(imageViewA)需要设置到scroll view的顶部,另外bottom item需要定义它的bottomAnchor到scrollView的底部滚动正确工作的顺序:
imageViewD.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor).isActive = true
您还在某些视图中同时使用 centerXAnchor
和 leftAnchor
,假设 centerXAnchor
与 leftAnchor
相同,只是从不同的角度描述它视图的一部分,因为您的 centerXAnchor
在 leftAnchor 之后,它将只使用 centerX,这意味着图像将在 scrollView 中居中。
我建议遵循此模式并从头开始重新构建您的约束,真正关注需要定义的锚点和位置。您也可以使用 Interface Builder 来添加视图,但是学习像这样定义约束将在未来被证明是一项非常有价值的技能,并且有助于保持您的代码非常清晰和干净。
更新:
此代码将完全按照您的要求执行,请注意滚动视图的高度和宽度以及我用来提供 space 的常量。每个 imageView 都按照我上面所说的方式定义,从左到右,最后一个项目具有左右约束。删除您的 setupLayout 并将其替换为这个(确保在必要时更改约束以适合您的应用程序):
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
}
这是该代码的作用的 gif:
别忘了在
中调用viewDidLoad()
setupLayout
override func viewDidLoad() { super.viewDidLoad() setupLayout() // Do any additional setup after loading the view, typically from a nib. }