我的应用程序有一个功能,您可以在其中回答有关您关注的人的问题,例如(选项 A、B、C、D 是用户姓名所在的位置):
这个想法是,你回答一个关于用户的问题,然后它从你从 firebase 数据库中关注的人中随机洗牌。这些图片是用户在注册时上传的个人资料图片,按照问题答案中的左上角、右上角、左下角、右下角的顺序显示。
我正在尝试使用 UIScrollView,但所有图像都堆叠在一起,而不是能够在它们之间滑动(并且问题标签消失了)
有没有办法让 ScrollView 工作,或者有没有更好/更有效的方法来集成 UICollectionView(我看到一些帖子推荐这种方法用于类似的事情)?
我是新手,所以希望得到任何帮助,在此先感谢:)
更新:
我已经编辑了约束,因此 ImageView 的左右 anchor 应该是正确的,并在 Storyboard上的 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
}
最佳答案
您的 imageView 彼此重叠的原因是您定义了:
imageViewB.leftAnchor.constraint(equalTo: imageViewA.leftAnchor)
这转化为:imageView B 的左侧与 imageViewA 的左侧相同,本质上是说它们的左侧都从同一位置开始,因此它们将彼此重叠。
因此您需要从左到右定义每个项目:
imageViewB.leftAnchor.constraint(equalTo: imageViewA.rightAnchor)
imageViewB 的左侧,从 imageViewA 的右侧开始。 imageView Cs leftAnchor 将等于 imageViewBs right 等等,直到到达最终的 imageViewD,您需要让 leftAnchor 等于 imageViewCs rightAnchor 和 imageViewDs rightAnchor 等于 scrollViews rightAnchor 以允许滚动正常工作。
如果你想向下滚动而不是从左到右滚动,你也可以使用 scrollView 轻松地做你想做的事情,而不是左右 anchor ,使用 centerXAnchors
使 View 在 scrollView 中居中
你需要想象你正在向某人描述布局,ImageViewA 在顶部,所以它的顶部 anchor 等于 scrollViews 顶部 anchor 。
对于 imageViewB,您可以从上到下进行相同的描述,因此:
imageViewB.topAnchor.constraint(equalTo: imageViewA.bottomAnchor).isActive = true
ImageView B 的顶部从 ImageView A 的底部开始,然后您对其余部分执行相同的操作,如下所示:
imageViewC.topAnchor.constraint(equalTo: imageViewC.bottomAnchor).isActive = true
和
imageViewD.topAnchor.constraint(equalTo: imageViewC.bottomAnchor).isActive = true
因为它是一个 scrollView,而你正在向下滚动,top (imageViewA) 需要设置到 ScrollView 的顶部,另外 bottom item 需要将它的 bottomAnchor 定义到 scrollView 的底部,以便滚动以正常工作:
imageViewD.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor).isActive = true
您还在某些 View 中同时使用了 centerXAnchor
和 leftAnchor
,假设 centerXAnchor
与 leftAnchor
但只是从 View 的不同部分描述它,因为您的 centerXAnchor
位于 leftAnchor 之后,它只会使用 centerX,这意味着图像将在 scrollView 中居中。
我建议遵循此模式并从头开始重新构建约束,真正关注需要定义的 anchor 和位置。您也可以使用 Interface Builder 来添加 View ,但是学习像这样定义约束将在未来被证明是一项非常有值(value)的技能,并且有助于保持您的代码非常清晰和干净。
更新:
此代码将完全按照您的要求执行,请注意 ScrollView 的高度和宽度以及我用来提供空间的常量。每个 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. }
关于ios - UIScrollView 或 UICollectionView 按从 firebase 调用的顺序滑动图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54984711/