关闭时无法重新加载背景图片

时间:2019-10-10 09:16:52

标签: ios swift

当用户从将被关闭的ViewController中选择背景图像时,我需要在MainVC中重新加载背景图像,但我不知道如何操作。任何想法? 附言在MainVC中,我有一个collectionView,每个单元格都包含另一个collectionView,并且这些collectionViews都有一个自定义单元格。 当用户选择背景图像时,该图像将传递到自定义单元格,应设置为背景。

协议

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

具有ColletionView的MainVC单元

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 :(得分:0)

您几乎完全正确。

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
    }
}
  • 更新:
MainVC 中的

cellForItemAt

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 {
        ...
    }
}
QuoteCell 中的

cellForItemAt

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
}

如果您仍然无法使其正常工作,我将要求您共享两个collectionViews中的cellForItemAt方法中的代码。