Как добавить изображение в представление прокрутки в Swift 5 - Xcode 11 - PullRequest
0 голосов
/ 27 марта 2020

Я создал вид прокрутки, в который встроено изображение, которое отображает изображения структуры, которую я создал. Над представлением прокрутки находится метка, которая отображает заголовок изображения. Структура (scrollViewDataStruct) содержит как заголовок, так и UIImage. Я назначаю эту структуру переменной в классе ViewController, которая называется scrollViewData.

scrollViewData - это массив scrollViewDataStruct. В настоящее время, для тестирования, он содержит пять предустановленных индексов (или значений ... как вы хотите их называть). В моем приложении также есть кнопка (за пределами прокрутки), которая при нажатии открывает камеру (или библиотеку фотографий) и позволяет пользователю загружать фотографии в приложение. Затем эта фотография помещается в переменную UIImage, а затем эта переменная добавляется к scrollViewData (пример в строках 100 и 101). Я хочу, чтобы мой scrollView обновлял imageViews, когда пользователь добавляет новую фотографию (так, когда вызывается didFinishPickingMedia). Это все работает отлично ... изображение правильно добавляется к scrollViewData. Проблема возникает, как только пользователь касается scrollView (после загрузки изображения). Приложение аварийно завершает работу и в строке 73 (которая находится в функции scrollViewDidScroll) выдает следующую ошибку: «Поток 1: Неустранимая ошибка: неожиданно обнаружен ноль при развертывании необязательного значения.»

Я понимаю, что функция viewDidLoad вызывается только один раз (при первом запуске этого контроллера просмотра). Я попытался взять весь код (кроме назначения делегата [строка 32] и присвоения значений scrollViewData [строки 34-38]) из viewDidLoad и размещения его в viewWillAppear, но затем он дублирует все метки, которые находятся над scrollView (я предполагаю, потому что он запускается несколько раз ... поэтому он просто накладывает один вид поверх другого). Это также происходит, если вместо того, чтобы поместить весь этот код в viewWillAppear, я поместил его в функцию didFinishPickingMedia. Из-за этого я просто положил все это обратно в viewDidLoad, как в моем коде ниже, и решил, что буду искать помощи у кого-то более опытного.

Я новичок во всех языках программирования (в программировании Вообще), поэтому, пожалуйста, дайте ответы на свои вопросы и объясните их. Кроме того, когда вы публикуете код, пожалуйста, покажите весь класс, чтобы я мог знать, куда поместить включенные вами элементы. Также это позволяет меньше путать с кем-либо еще, кто посещает этот пост с той же проблемой.

Спасибо!

Вот мой код:

import UIKit

struct scrollViewDataStruct {
    let title : String?
    let image : UIImage?
}

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIScrollViewDelegate {

    @IBOutlet weak var scrollView: UIScrollView!

    var scrollViewData = [scrollViewDataStruct]()

    var viewTagValue = 100
    var tagValue = 200

    var imageTaken = UIImage()
    var imagePicker = UIImagePickerController()


    override func viewDidLoad() {
        super.viewDidLoad()

        scrollView.delegate = self

            scrollViewData = [scrollViewDataStruct.init(title: "First", image: #imageLiteral(resourceName: "20191028_220009")),
            scrollViewDataStruct.init(title: "Second", image: #imageLiteral(resourceName: "20191028_214433")),
            scrollViewDataStruct.init(title: "Third", image: #imageLiteral(resourceName: "20191028_214648")),
            scrollViewDataStruct.init(title: "Fourth", image: #imageLiteral(resourceName: "20191028_220457")),
            scrollViewDataStruct.init(title: "Fifth", image: #imageLiteral(resourceName: "20191028_220152"))]



        scrollView.contentSize.width = self.scrollView.frame.width * CGFloat(scrollViewData.count)
        var i = 0
        for data in scrollViewData {
            let view = CustomView(frame: CGRect(x: 10 + (self.scrollView.frame.width * CGFloat(i)), y: 60, width: self.scrollView.frame.width - 20, height: self.scrollView.frame.height - 90))
            view.imageView.image = data.image
            view.tag = i + viewTagValue
            self.scrollView.addSubview(view)


            let label = UILabel(frame: CGRect.init(origin: CGPoint.init(x: 0, y: 20), size: CGSize.init(width: 0, height: 40)))
            label.text = data.title
            label.font = UIFont.boldSystemFont(ofSize: 30)
            label.textColor = UIColor.black
            label.sizeToFit()
            label.tag = i + tagValue
            if i  == 0 {
                label.center.x = view.center.x
            } else {
                label.center.x = view.center.x - self.scrollView.frame.width / 2
            }

            self.scrollView.addSubview(label)

            //Stays at bottom
            i += 1
        }
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if scrollView == scrollView {
            for i in 0..<scrollViewData.count {
                let label = scrollView.viewWithTag(i + tagValue) as! UILabel
                let view = scrollView.viewWithTag(i + viewTagValue) as! CustomView

                let scrollContentOffset = scrollView.contentOffset.x + self.scrollView.frame.width
                let viewOffset = (view.center.x - scrollView.bounds.width / 3) - scrollContentOffset
                label.center.x = scrollContentOffset - ((scrollView.bounds.width / 4 - viewOffset) / 2)


            }
        }
    }





    @IBAction func takePhotoButton(_ sender: Any) {

        imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .camera

        present(imagePicker, animated: true, completion: nil)

    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        imageTaken = (info[.originalImage] as? UIImage)!
        scrollViewData.append(scrollViewDataStruct.init(title: "Random", image: imageTaken))
        imagePicker.dismiss(animated: true, completion: nil)

        print(scrollViewData.count)

        }




}


class CustomView: UIView {

    let imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = UIColor.lightGray
        imageView.contentMode = .scaleAspectFit
        return imageView
    }()


    override init(frame: CGRect) {
        super.init(frame: frame)

        self.addSubview(imageView)

        imageView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        imageView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
        imageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
...