UIScrollView: Показать профиль пользователя Изображения в виде прокрутки, когда имя пользователя вызывается из firebase - PullRequest
0 голосов
/ 24 февраля 2019

Я создаю приложение, в котором пользователь отвечает на вопросы с выбором из 4 случайных пользователей, за которыми они следуют.В настоящее время он вызывает случайные имена из моей базы данных Firebase.У каждого пользователя есть изображение профиля, которое он загружает при регистрации, и оно сохраняется в том же месте, что и полное имя пользователя.

Я бы хотел, чтобы изображение профиля вызывалось одновременно с полными именами и отображалось в UIScrollView на экране в том порядке, в котором эти имена называются (например, сначала выбирается опция «Изображение пользователя», затемвыделите вариант «Пользовательское изображение» и т. д.) - как это изображение

До сих пор полные имена вызывались и отображались на кнопке, и я могу получить доступ к хранилищу Firebase для URL, но я неНе знаю, как получить profileImageUrl из firebase для отображения в этом порядке на скроллвью, когда имена пользователей выбираются случайным образом, пока у меня есть это:

@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)
}

Обновление: как это выглядит

то, как теперь выглядят изображения вместо возможности пролистывать их

РЕДАКТИРОВАТЬ: Попытка сделать так, чтобы вы могли провести между изображениями - но я получаю ошибку: Тема 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 голосов
/ 25 февраля 2019

Создайте словарь из names:profileImageUrl

var namesWithUrl = [String : String]()

и вместо names.append(name) do:

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

, так что теперь имя хранится в словаре с его правильным profileImageUrlи поэтому словарь будет выглядеть так:

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

Тогда, если вы используете SDWebImage , вы можете сделать это очень просто:

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

Это позволит легко установить изображениев свой imageView, и вы можете просто добавить эту строку под каждым из них.

РЕДАКТИРОВАТЬ: Добавление видов изображения для просмотра с прокруткой.

Вы можете добавить представление изображения через раскадровку на вид прокруткиили вы можете добавить их программно следующим образом:

Сначала объявите их:

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

Затем мне нравится иметь функцию setupLayout для обработки моих представлений:

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

}

Там вы можете увидеть, как мы помещаем imageViewB ниже imageViewA, и ширина такая же, как у scrollview -10, что дает немного места.

, затем вызовите setupLayout() в viewDidLoad().они будут пустыми, пока вы не разместите изображения на них.с optionAImageView.sd_setImage(with: URL(namesWithUrl[name[1]]))

Обновление:

Возможно, вам потребуется изменить строковую версию URL-адреса на URL для SD_setimage, например:

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

Ошибка индекса можетозначает, что вы неправильно инициализируете словарь, как я тестировал, и он должен работать нормально.

Обновление:

Проблема с вашим setupLayout заключается в том, что вы смешиваете автоматическое размещение с использованием фреймов.Я предполагаю, что ваши ограничения scrollViews определены в раскадровке, так что вот как вы должны настроить imageViews, чтобы ширина и высота были такими же, как у scrollView, и вы можете перемещаться между ними.Обратите внимание, что если вы хотите прокрутить по горизонтали, вам следует изучить использование UICollectionView.

В этом примере я создаю scrollView программно, вы можете просто сфокусироваться на imageViews, поскольку ваши ограничения сделаны в раскадровке.

import UIKit

class ViewController: UIViewController {

let scrollView = UIScrollView()
let imageViewA = UIImageView()
let imageViewB = UIImageView()
let imageViewC = UIImageView()
//Declaring the imageViews

override func viewDidLoad() {
    super.viewDidLoad()

    setupLayout()
    // Do any additional setup after loading the view, typically from a nib.
}

func setupLayout() {
    view.addSubview(scrollView)
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    scrollView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -10).isActive = true
    scrollView.backgroundColor = .gray
    //setting up the size of the scrollView

    scrollView.addSubview(imageViewA)
    //This means we are using autoLayout, building the views and setting their size based on how their constraints relate to other objects
    imageViewA.translatesAutoresizingMaskIntoConstraints = false
    imageViewA.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    //Setting the imageViewA top anchor to the scrollView topanchor we are essentially saying the top of this imageView starts at the top of the scroll view
    imageViewA.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -10).isActive = true
    //Here the imageViews width is equal to the scrollViews width, (-10 is optional if you want it not to touch the edges)
    imageViewA.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
     //CenterXAnchor here I am making sure the imageView is centered in the scrollView
    imageViewA.heightAnchor.constraint(equalTo: scrollView.heightAnchor, constant: -10).isActive = true
     //same with the height
    imageViewA.backgroundColor = .cyan
     //Background just for my testing as I dont have any images to sue
    imageViewA.contentMode = .scaleAspectFit
     //This is how you want the image to scale into the view for when you set it.
    scrollView.addSubview(imageViewB)
    imageViewB.translatesAutoresizingMaskIntoConstraints = false
    imageViewB.topAnchor.constraint(equalTo: imageViewA.bottomAnchor, constant: 10).isActive = true
    //Because we want to scroll down, the top anchor of imageViewB is equal to the bottom anchor of imageViewA meaning the top of B starts at the bottom of A
    imageViewB.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
   imageViewB.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -10).isActive = true
    //Height and widths are the same.
    imageViewB.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
    imageViewB.backgroundColor = .cyan
    imageViewB.contentMode = scaleAspectFit
    scrollView.addSubview(imageViewC)
    imageViewC.translatesAutoresizingMaskIntoConstraints = false
    imageViewC.topAnchor.constraint(equalTo: imageViewB.bottomAnchor, constant: 10).isActive = true
    //imageViewCs top starts at bottom of B
    imageViewC.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
    imageViewC.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -10).isActive = true
    imageViewC.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
    imageViewC.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
     //for the final view, it needs to be connected to the bottom so the scrollView is able to scroll.
    imageViewC.backgroundColor = .cyan
    imageViewC.contentMode = .scaleAspectFit
}


}

Это дает мне квадратный Scrollview, который показывает imageViewA и позволяет мне прокручивать вниз и видеть imageViewB, а затем imageView C

Вывод этого кода, scrollView установлен в centerYanchor of viewпоэтому он останавливается на середине, синие квадраты - это imageViews, image1 показывает, как он запускается, вы можете увидеть ImageViewA, затем image2 показывает, как вы можете перейти к следующему изображению: enter image description here

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...