UIScrollView:从Firebase调用用户名时,在滚动视图中显示用户配置文件图像

时间:2019-02-24 19:13:38

标签: ios swift firebase uiscrollview

我正在构建一个应用程序,其中用户通过选择的4个随机用户来回答问题。目前,它从我的Firebase数据库中调用随机名称。每个用户在注册时都有一个上传的个人资料图片,该图片与用户全名保存在同一位置。

我希望配置文件图像与全名同时被调用,并按照名称被调用的顺序显示在屏幕的UIScrollView上(例如,因此先显示选项A用户图像,然后滚动到选项B用户图片等)-like this image

到目前为止,全名被调用并显示在按钮上,我可以访问Firebase存储的URL,但是我不知道如何从firebase获取profileImageUrl以便在用户使用时以滚动顺序显示名称是随机选择的,到目前为止,我有这个名称:

@IBOutlet weak var pinionImagesScrollView: UIScrollView!
@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!

        let numberOfKeys = randomKeyArray.count
        var namesRemaining = numberOfKeys
        var names = [String]()
        var profileImages = [String]()

        for i in 0..<numberOfKeys {
            let thisUserKey = randomKeyArray[i]
            let userRef = self.ref.child("users").child(thisUserKey)
            userRef.observeSingleEvent(of: .value, with: { snapshot in
                let name = snapshot.childSnapshot(forPath: "fullname").value as! String
                let profileImageUrl = snapshot.childSnapshot(forPath: "profileImageUrl").value as! String
                print(name)
                namesRemaining -= 1
                names.append(name)

                // Another array for images
                print(profileImageUrl)
                profileImages.append(profileImageUrl)

                self.currIds.append(thisUserKey)
                if namesRemaining == 0 {
                    self.currNames = names
                    self.optionA.setTitle(names[0], for: .normal)
                    self.optionA.backgroundColor = UIColor.orange
                    self.optionB.setTitle(names[1], for: .normal)
                    self.optionB.backgroundColor = UIColor.orange
                    self.optionC.setTitle(names[2], for: .normal)
                    self.optionC.backgroundColor = UIColor.orange
                    self.optionD.setTitle(names[3], for: .normal)
                    self.optionD.backgroundColor = UIColor.orange
                }
            })
        }

感谢您的帮助/解释,谢谢:)

编辑代码更新:

@IBOutlet weak var imagePageControl: UIPageControl!
@IBOutlet weak var userImageScrollView: UIScrollView!
@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!

var user: UserModel?

override func viewDidLoad() {
    super.viewDidLoad()
    loadNewQuestion()
    getFourRandomNodesAndPrintUserName()
    imagePageControl.numberOfPages = namesWithUrl.count
    setupLayout()
}


var ref: DatabaseReference = Database.database().reference()
var currNames: [String] = []
var currIds: [String] = []
var names = [String]()
var namesWithUrl = [String : String]()
var frame = CGRect(x: 0, y: 0, width: 0, height: 0)
var imageViewA = UIImageView()
var imageViewB = UIImageView()
var imageViewC = UIImageView()
var imageViewD = UIImageView()

func setupLayout() {

    userImageScrollView.addSubview(imageViewA)
    imageViewA.translatesAutoresizingMaskIntoConstraints = false
    imageViewA.widthAnchor.constraint(equalTo: userImageScrollView.widthAnchor, constant: -10).isActive = true
    imageViewA.heightAnchor.constraint(equalToConstant: 60).isActive = true
    imageViewA.topAnchor.constraint(equalTo: userImageScrollView.topAnchor, constant: -5).isActive = true

    userImageScrollView.addSubview(imageViewB)
    imageViewB.translatesAutoresizingMaskIntoConstraints = false
    imageViewB.widthAnchor.constraint(equalTo: userImageScrollView.widthAnchor, constant: -10).isActive = true
    imageViewB.heightAnchor.constraint(equalToConstant: 60).isActive = true
    imageViewB.topAnchor.constraint(equalTo: imageViewA.bottomAnchor, constant: 5).isActive = true

    userImageScrollView.addSubview(imageViewC)
    imageViewC.translatesAutoresizingMaskIntoConstraints = false
    imageViewC.widthAnchor.constraint(equalTo: userImageScrollView.widthAnchor, constant: -10).isActive = true
    imageViewC.heightAnchor.constraint(equalToConstant: 60).isActive = true
    imageViewC.topAnchor.constraint(equalTo: imageViewB.bottomAnchor, constant: 5).isActive = true

    userImageScrollView.addSubview(imageViewD)
    imageViewD.translatesAutoresizingMaskIntoConstraints = false
    imageViewD.widthAnchor.constraint(equalTo: userImageScrollView.widthAnchor, constant: -10).isActive = true
    imageViewD.heightAnchor.constraint(equalToConstant: 60).isActive = true
    imageViewD.topAnchor.constraint(equalTo: imageViewC.bottomAnchor, constant: 5).isActive = true
    imageViewD.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor, constant: -5).isActive = true
}

   // Each view is attached to the bottom of the previous view, and the final must be attached to the bottom of the scroll view in order for it to scroll properly.

func getFourRandomNodesAndPrintUserName() {
    self.currNames = []
    self.currIds = []

    var myKeyArray = [String]()
    guard let uid = Auth.auth().currentUser?.uid else {
        return
    }

    let ref = self.ref.child("following").child(uid)
    //retreives all nodes in the following node
    ref.observeSingleEvent(of: .value, with: { snapshot in
        print(snapshot.children.allObjects)
        for child in snapshot.children { //build the array of keys
            let snap = child as! DataSnapshot
            let key = snap.key
            myKeyArray.append(key)
        }

        var randomKeyArray = [String]()
        let numFollowers = min(4, myKeyArray.count)
        for _ in 0..<numFollowers { //will iterate four times
            let count = myKeyArray.count //get the number of elements
            let randomInt = Int.random(in: 0..<count) //get a random index for the array
            let randomUserKey = myKeyArray[randomInt]
            randomKeyArray.append(randomUserKey)
            myKeyArray.remove(at: randomInt) //remove that object so it's not selected again
        }

        let numberOfKeys = randomKeyArray.count

        var namesRemaining = numberOfKeys

        for i in 0..<numberOfKeys {
            let thisUserKey = randomKeyArray[i]
            let userRef = self.ref.child("users").child(thisUserKey)
            userRef.observeSingleEvent(of: .value, with: { snapshot in
                let name = snapshot.childSnapshot(forPath: "fullname").value as! String
                let profileImageUrl = snapshot.childSnapshot(forPath: "profileImageUrl").value as! String

                print(name)
                print(profileImageUrl)
                namesRemaining -= 1
                self.names.append(name)
                self.namesWithUrl[name] = profileImageUrl


                self.currIds.append(thisUserKey)

                if numFollowers <= 3 {
                    self.optionA.setTitle("Follow\nat least\n4 friends!", for: .normal)
                    self.optionA.titleLabel?.textAlignment = .center
                    self.optionA.setTitleColor(UIColor.lightGray, for: .normal)
                    self.optionA.isEnabled = false
                    self.optionB.setTitle("Follow\nat least\n4 friends!", for: .normal)
                    self.optionB.titleLabel?.textAlignment = .center
                    self.optionB.setTitleColor(UIColor.lightGray, for: .normal)
                    self.optionB.isEnabled = false
                    self.optionC.setTitle("Follow\nat least\n4 friends!", for: .normal)
                    self.optionC.titleLabel?.textAlignment = .center
                    self.optionC.setTitleColor(UIColor.lightGray, for: .normal)
                    self.optionC.isEnabled = false
                    self.optionD.setTitle("Follow\nat least\n4 friends!", for: .normal)
                    self.optionD.titleLabel?.textAlignment = .center
                    self.optionD.setTitleColor(UIColor.lightGray, for: .normal)
                    self.optionD.isEnabled = false
                }
                else if namesRemaining == 0 {
                    self.currNames = self.names
                    self.optionA.setTitle(self.names[0], for: .normal)
                    self.optionA.backgroundColor = UIColor.orange
                    self.imageViewA.sd_setImageLoad(URL(namesWithUrl[name[0]])) //this is where i am getting the error - here you want to set the image to the imageView not the scrollView

                    self.optionB.setTitle(self.names[1], for: .normal)
                    self.optionB.backgroundColor = UIColor.orange

                    self.optionC.setTitle(self.names[2], for: .normal)
                    self.optionC.backgroundColor = UIColor.orange
                    self.optionD.setTitle(self.names[3], for: .normal)
                    self.optionD.backgroundColor = UIColor.orange
                }
                self.userImageScrollView.contentSize = CGSize(width: (self.userImageScrollView.frame.size.width * CGFloat(self.namesWithUrl.count)), height: self.userImageScrollView.frame.size.height)
                self.userImageScrollView.delegate = self
            })
        }
    })
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    let pageNumber = userImageScrollView.contentOffset.x / userImageScrollView.frame.size.width
    imagePageControl.currentPage = Int(pageNumber)
}

更新:外观

how images look now instead of being able to swipe between them

编辑:尝试制作图像以便在图像之间滑动-但出现错误:应用程序委托上的线程1 SIGBART

var frame = CGRect(x: 0, y: 0, width: 0, height: 0)

func setupLayout() {
    frame.origin.x = userImageScrollView.frame.size.width * CGFloat(4)
    frame.size = userImageScrollView.frame.size

    let imageViewA = UIImageView(frame: frame)
    userImageScrollView.addSubview(self.imageViewA)

    imageViewA.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor, constant: -5).isActive = true


    let imageViewB = UIImageView(frame: frame)
    userImageScrollView.addSubview(self.imageViewB)

    imageViewB.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor, constant: -5).isActive = true
    imageViewB.leftAnchor.constraint(equalTo: imageViewA.leftAnchor)

    let imageViewC = UIImageView(frame: frame)
    userImageScrollView.addSubview(imageViewC)

    imageViewC.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor, constant: -5).isActive = true
    imageViewC.leftAnchor.constraint(equalTo: imageViewB.leftAnchor)

    let imageViewD = UIImageView(frame: frame)
    userImageScrollView.addSubview(imageViewD)

    imageViewD.bottomAnchor.constraint(equalTo: userImageScrollView.bottomAnchor, constant: -5).isActive = true
    imageViewD.leftAnchor.constraint(equalTo: imageViewC.leftAnchor)

    self.userImageScrollView.contentSize = CGSize(width: (self.userImageScrollView.frame.size.width * CGFloat(4)), height: self.userImageScrollView.frame.size.height)
    self.userImageScrollView.delegate = self
}

1 个答案:

答案 0 :(得分:0)

制作 void _moveDown(GlobalKey myKey) { final keyContext = myKey.currentContext; if (keyContext != null) { final box = keyContext.findRenderObject() as RenderBox; _scrollController.animateTo(_scrollController.offset + box.size.height, duration: Duration(milliseconds: 100), curve: Curves.linear); } } 的字典

names:profileImageUrl

而不仅仅是var namesWithUrl = [String : String]()

names.append(name)

因此,现在该名称保存在具有正确的profileImageUrl的字典中,因此该字典将如下所示:

names.append(name)
namesWithUrl[name] = profileImageUrl

然后,如果您使用SDWebImage,则可以非常简单地完成此操作:

[name1value : name1URl, name2value : name2URl, ...]

这将轻松地将图像设置为您的imageView,您只需在每一行下添加该行即可。

编辑:将图像视图添加到滚动视图。

您可以通过情节提要将图像视图添加到滚动视图中,也可以像下面这样以编程方式添加它们:

首先声明它们:

self.optionA.setTitle(names, for: .normal)
self.optionA.backgroundColor = UIColor.orange
self.optionA.sd_setBackgroundImage(with: URL(namesWithUrl[name[1]]), for: .normal)
//If using the button image

self.optionB.setTitle(names[1], for: .normal)
self.optionB.backgroundColor = UIColor.orange
optionAImageView.sd_setImage(with: URL(namesWithUrl[name[1]]))
//if using a seperate imageView

然后,我想拥有一个setupLayout函数来处理我的视图:

var imageViewA = UIImageView()
var imageViewB = UIImageView()

您可以看到我们如何将imageViewB放在imageViewA下方,并且宽度与滚动视图-10相同,只留出一点空间。

然后在func setupLayout() { pinionImagesScrollView.addsubview(imageViewA) imageViewA.translatesAutoResizingMaskIntoConstraints = false imageViewA.widthAnchor.constraint(equalTo: pinionImagesScrollView.widthAnchor, constant: -10).isActive = true imageViewA.heightAnchor.constraint(equalToConstant: 60).isActive = true imageViewA.topAnchor.constraint(equalTo: pinionImagesScrollView.topAnchor, constant: -5).isActive = true pinionImagesScrollView.addsubview(imageViewA) imageViewB.translatesAutoResizingMaskIntoConstraints = false imageViewB.widthAnchor.constraint(equalTo: pinionImagesScrollView.widthAnchor, constant: -10).isActive = true imageViewB.heightAnchor.constraint(equalToConstant: 60).isActive = true imageViewB.topAnchor.constraint(equalTo: imageViewA.bottomAnchor, constant: -5).isActive = true } 中呼叫setupLayout()。在将图像放置到它们之前,它们将是空的。与viewDidLoad()

更新:

您可能需要将URL的字符串版本更改为SD_setimage的URL,如下所示:

optionAImageView.sd_setImage(with: URL(namesWithUrl[name[1]]))

下标错误可能表示您由于我的测试而将字典初始化错误,并且应该可以正常工作。

更新:

setupLayout的问题是您将自动布局与使用帧混合在一起。我假设您的scrollViews约束是在情节提要中定义的,所以这是设置imageViews的方式,以便宽度和高度与scrollView相同,并且可以在它们之间滚动。请注意,如果您想水平滚动,则应该研究使用UICollectionView代替。

在此示例中,我以编程方式创建了scrollView,因为您的约束是在情节提要中进行的,您可以只关注imageViews。

 let optionAUrl = URL.init(string: nameUrls[names[0]])
  imageView.sd_setImage(with: optionAUrl)

这给了我一个正方形的Scrollview,它显示了imageViewA,并允许我向下滚动并查看imageViewB和imageView C

此代码的输出,scrollView设置为viewYanchor,所以它停在中间,蓝色方块是imageViews,image1显示了它如何启动,您可以看到ImageViewA,然后image2显示了如何滚动到下一个图像:{ {3}}

enter image description here