Не удается перезагрузить фоновое изображение при отклонении - PullRequest
0 голосов
/ 10 октября 2019

Мне нужно перезагрузить фоновое изображение в MainVC, когда пользователь выбирает его из ViewController, который будет отклонен, но я не могу понять, как. Любая идея? Ps. В MainVC у меня есть collectionView, каждая ячейка содержит другой collectionView, и у этих collectionView есть пользовательская ячейка. Когда пользователь выбирает фоновое изображение, оно передается в пользовательскую ячейку и должно быть задано в качестве фона.

Протокол

protocol ThemeDelegate {
    func handlePassThemeData(data: UIImage)
}

MainVC

class MainVC: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, ThemeDelegate {

    var currentTheme = UIImage(named: "4")!
    let collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.register(QuoteCell.self, forCellWithReuseIdentifier: reuseIdentifier)
        collectionView.register(FeaturedCell.self, forCellWithReuseIdentifier: featuredReuseIdentifier)
        collectionView.register(AuthorCell.self, forCellWithReuseIdentifier: authorReuseIdentifier)
        return collectionView
    }()

    override func viewDidLoad() {
    super.viewDidLoad
        setUpViews()
        setupNavigationBarItems()
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if indexPath.item == 0 {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! QuoteCell
            createGradientLayer(bounds: CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height), cell: cell)
            cell.delegate = self
            cell.imageToPass = currentTheme
            return cell
        } else if indexPath.item == 1 {
            ...
        }
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        if indexPath.item == 0 {
            return CGSize(width: view.frame.width, height: view.frame.height / 1.5)
        } else if indexPath.item == 1 {
            return CGSize(width: view.frame.width, height: view.frame.height / 1.95)
        } else {
            return CGSize(width: view.frame.width, height: 160)
        }
    }

    func setupNavigationBarItems() {
        let themesButton = setUpBarButton(image: #imageLiteral(resourceName: "themes_icon_color"))
        themesButton.addTarget(self, action: #selector(handleThemesTapped), for: .touchUpInside)
        navigationItem.leftBarButtonItem = UIBarButtonItem(customView: themesButton)
    }

    func setUpViews() {
        view.addSubview(collectionView)
        collectionView.delegate = self  
        collectionView.dataSource = self
        collectionView.anchors(top: view.safeAreaLayoutGuide.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
    }

    func handlePassThemeData(data: UIImage) {
        self.currentTheme = data
        self.collectionView.reloadData()
    }

    @objc func handleThemesTapped() {
        let themesVc = ThemesVC(collectionViewLayout: UICollectionViewFlowLayout())
        let navController = UINavigationController(rootViewController: themesVc)
        themesVc.delegate = self                
        navigationController?.present(navController, animated: true, completion: nil)
    }
}

Ячейка MainVCс ColletionView

class QuoteCell: UICollectionViewCell, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {

    var imageToPass = UIImage(named: "2")!
    let collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.register(QuoteSubCell.self, forCellWithReuseIdentifier: "cell")
        return collectionView
    }()

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

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! QuoteSubCell
        cell.quote = quotes[indexPath.item]

        cell.setupCell(with: imageToPass)
        return cell
    }

    func setUpViews() {
        addSubview(collectionView)
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.anchors(top: nameLabel.bottomAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor)
    }
}

CustomCell

class QuoteSubCell: UICollectionViewCell {

    var backgroundImage: UIImageView = {
        let view = UIImageView()
        view.clipsToBounds = true
        view.contentMode = .scaleAspectFill
        view.image = UIImage(named: "2")
        return view
    }()

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

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

    func setupCell(with image: UIImage) {
        backgroundImage.image = image
    }

    func setUpViews() {
        contentView.addSubview(backgroundImage)
        backgroundImage.anchors(top: contentView.topAnchor, left: contentView.leftAnchor, bottom: contentView.bottomAnchor, right: contentView.rightAnchor)
    }
}

ThemesVC, где пользователь выбирает фон

class ThemesVC: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    var delegate: ThemeDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.dataSource = self
        collectionView.delegate = self
        setUpViews()
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ThemeCell
        cell.backgroundImage.image = themeCell.backgroundImages[indexPath.item]
        cell.layer.cornerRadius = 10
        return cell
    }

    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        delegate?.handlePassThemeData(data: themeCell.backgroundImages[indexPath.item])        
        self.navigationController?.dismiss(animated: true, completion: nil)
    }

    func setUpViews() {
        collectionView.register(ThemeCell.self, forCellWithReuseIdentifier: reuseIdentifier)
        collectionView.backgroundColor = UIColor(white: whitePoint, alpha: 1)
        collectionView.alwaysBounceVertical = true
        collectionView.showsVerticalScrollIndicator = false
    }
}

1 Ответ

0 голосов
/ 10 октября 2019

Вы почти правильно поняли.

class MainVC: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, ThemeDelegate {

    //MARK: Properties
    var currentTheme = UIImage(named: "defaultImage")

    override func viewDidLoad() {
        super.viewDidLoad()
        setUpViews()
    }

    func setUpViews() {
        view.addSubview(collectionView)
        collectionView.anchors(top: view.safeAreaLayoutGuide.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
    }
    func handlePassThemeData(data: UIImage) {
        self.currentTheme = data //override your variable with the new image
        self.collectionView.reloadData() //reload the collectionView, to apply the change
    }

    @objc func handleThemesTapped() {
        let themesVc = ThemesVC(collectionViewLayout: UICollectionViewFlowLayout())
        themesVc.delegate = self       
        //no need to instantiate a new navigationController. Just push to the current one, if you want the animation from right, and not from bottom-up.         
        navigationController?.pushViewController(themesVc, animated: true)
    }
}

На делегатов всегда должны быть слабые ссылки.

class ThemesVC: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    weak var delegate: ThemeDelegate?

    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        delegate?.handlePassThemeData(data: themeCell.backgroundImages[indexPath.item])
        self.navigationController?.popViewController(animated: true)
    }
}

Кроме того, вам не нужно создавать статическую переменную внутри ячейки. Вместо этого передайте currentImage переменной вашей ячейки imageToPass в методе cellForItemAt.

class QuoteCell: UICollectionViewCell, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {

    var imageToPass = UIImage(named: "defaultImage")//pass this image to the cells inside the collectionView

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

    func setUpViews() {
        addSubview(collectionView)
        collectionView.anchors(top: nameLabel.bottomAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor)
    }
}

Наконец, ваши субэлементы должны показать ваше изображение:

class QuoteSubCell: UICollectionViewCell {

    var backgroundImage: UIImageView = {
        let view = UIImageView()
        view.clipsToBounds = true
        view.contentMode = .scaleAspectFill
        view.image = QuoteSubCell.chosenTheme
        return view
    }()

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

    private func setUpViews() {
        contentView.addSubview(backgroundImage)
        backgroundImage.anchors(top: contentView.topAnchor, left: contentView.leftAnchor, bottom: contentView.bottomAnchor, right: contentView.rightAnchor)
    }

    func setupCell(with image: UIImage) { //use this setup function inside "cellForItemAt" method, where you will pass the `imageToPass` image.

        backgroundImage.image = image
    }
}
  • ОБНОВЛЕНИЕ:

cellForItemAt внутри MainVC :

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if indexPath.item == 0 {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! QuoteCell
        createGradientLayer(bounds: CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height), cell: cell)
        cell.delegate = self
        cell.imageToPass = currentTheme //here you pass the image the 1st time
        return cell
    } else if indexPath.item == 1 {
        ...
    }
}

cellForItemAt внутри QuoteCell :

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! QuoteSubCell
    cell.quote = quotes[indexPath.item]
    cell.setupCell(with: imageToPass) //here you pass the image the second time
    return cell
}

Если вы все еще не можете заставить его работать, я попрошу вас поделиться кодом из cellForItemAt методов из обоих collectionViews.

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