从另一个类访问 viewController 元素

Posted

技术标签:

【中文标题】从另一个类访问 viewController 元素【英文标题】:Acess uiviewController element from another class 【发布时间】:2018-06-02 00:59:29 【问题描述】:

我正在处理这个项目,但是我的故事板的视图控制器中的元素存在问题,我想从另一个类更改它的属性! 我的第一种方法是在我的第二堂课中从视图控制器中实例化一个对象!在运行时返回 nil!

        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
//        let mainstampvc = MainStampVc().storyboard?.instantiateViewController(withIdentifier: "mainstampvc") as? MainStampVc
//        mainstampvc?.setstampimage(imageURL: list_images[indexPath.row])
        
        let msvc = mainstampvc()
        mainstampvc?.setstampimage(imageURL: list_images[indexPath.row])
    

我的第二个方法是在我的第二个类中再次实例化整个视图控制器,它什么都不做。

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
    let mainstampvc = MainStampVc().storyboard?.instantiateViewController(withIdentifier: "mainstampvc") as? MainStampVc
    mainstampvc?.setstampimage(imageURL: list_images[indexPath.row])

我想要的就是当我点击我的 uicollectionviewcell 更改我的 MainViewcontroller 视图之一的背景时。这是我所有的课程

viewcontroller.swift

import Foundation
import UIKit

class ViewController: UIViewController 
    @IBOutlet weak var stampholder: UIView!
    @IBAction func TextViewButton(_ sender: Any) 
        removerSubViews()
        addSubView(ViewName: "text")
    
    @IBAction func AViewButton(_ sender: Any) 
        removerSubViews()
        addSubView(ViewName: "mohr")
    
    @IBAction func BorderViewButton(_ sender: Any) 
    
    @IBAction func DlViewButton(_ sender: Any) 
    
    @IBOutlet weak var holderView: UIView!
    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        addSubView(ViewName: "mohr")
        let mainstampvc = self.storyboard?.instantiateViewController(withIdentifier: "mainstampvc")
        let mainstampview = mainstampvc?.view
        mainstampview?.frame = stampholder.frame
        stampholder.addSubview((mainstampview)!)
    
    func removerSubViews()
            for view in self.holderView.subviews
                view.removeFromSuperview()
            
    
    func addSubView(ViewName: String)
    
        if let subview = Bundle.main.loadNibNamed(ViewName, owner: self, options: nil)?.first as? UIView 
            self.holderView.addSubview(subview);
        
    
    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

mohrcollectionview.swift

import Foundation
import UIKit

class MohrCollectionViewController: UIView,UICollectionViewDataSource,UICollectionViewDelegate
    var mohrPath: String = ""
    var fileManager: FileManager!
    var list_images : [String] = []
    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        fileManager = FileManager.default
        let currentDir = Bundle.main.resourcePath
        mohrPath = currentDir!
        let mohrsPath = try? fileManager.contentsOfDirectory(atPath: mohrPath + "/mohr")
        list_images = mohrsPath!
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
        return list_images.count
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        collectionView.register(UINib(nibName: "mohrcell", bundle: nil), forCellWithReuseIdentifier: "mohrcell")
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mohrcell", for: indexPath) as! mohrCellController
        let image = UIImage(named: list_images[indexPath.row])
        cell.cellimage.image = image
        return cell
    
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        let mainstampvc = MainStampVc().storyboard?.instantiateViewController(withIdentifier: "mainstampvc") as? MainStampVc
        mainstampvc?.setstampimage(imageURL: list_images[indexPath.row])
    


mainstampvc.swift

import Foundation
import UIKit

class MainStampVc: UIViewController
    

    @IBOutlet weak var stampimage: UIImageView!
    override func viewDidLoad() 
        super.viewDidLoad()
        setstampimage(imageURL: "golbanafsh.png")
    
    public func setstampimage(imageURL: String)
    
        stampimage.image = UIImage(named: imageURL)
    

任何帮助将不胜感激

2

所以这是我的委托代码,但仍然没有:(

//
//  MohrCollectionViewController.swift
//  Mohrem
//
//  Created by shayan rahimian on 12/18/17.
//  Copyright © 2017 shayan rahimian. All rights reserved.
//
import Foundation
import UIKit



class MohrCollectionViewController: UIView,UICollectionViewDataSource,UICollectionViewDelegate,UpdateBackgroundDelegate
    var updatedelegate:UpdateBackgroundDelegate? = nil
    func updateBackground(imageURL: String) 
        print("mohr update back ground e balaE")
        if updatedelegate == nil 
            print("no delegate")
        else
            updatedelegate?.updateBackground(imageURL: imageURL)
        
    
    var mohrPath: String = ""
    var fileManager: FileManager!
    var list_images : [String] = []
    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        fileManager = FileManager.default
        let currentDir = Bundle.main.resourcePath
        mohrPath = currentDir!
        let mohrsPath = try? fileManager.contentsOfDirectory(atPath: mohrPath + "/mohr")
        list_images = mohrsPath!
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
        return list_images.count
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        collectionView.register(UINib(nibName: "mohrcell", bundle: nil), forCellWithReuseIdentifier: "mohrcell")
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mohrcell", for: indexPath) as! mohrCellController
        let image = UIImage(named: list_images[indexPath.row])
        cell.cellimage.image = image
        return cell
    
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        self.updateBackground(imageURL: list_images[indexPath.row])
    
    




//
//  MainStampvc.swift
//  Mohrem
//
//  Created by shayan rahimian on 12/19/17.
//  Copyright © 2017 shayan rahimian. All rights reserved.
//

import Foundation
import UIKit

protocol UpdateBackgroundDelegate : class 
    func updateBackground(imageURL: String)

class MainStampVc: UIViewController

    @IBOutlet weak var stampimage: UIImageView!
    override func viewDidLoad() 
        super.viewDidLoad()
        updateBackground(imageURL: "biggolabi.png")
        
    
    func updateBackground(imageURL: String) 
        // update your background in this funcion
        print("extension")
        print(imageURL)
        stampimage.image = UIImage(named: imageURL)
    


我做错了吗?

【问题讨论】:

应用程序的结构是什么?您想从第二个控制器更改第一个控制器的颜色吗?你有推送层次结构,模态......? @sci3nt15t 请明确问题所在。请显示相关代码。这将有助于更好地理解问题并快速解决问题。 您的部分问题是您有一个自定义的UIView,您将其称为控制器并将数据提供给另一个视图。这使得结构难以使用。 您能分享您的示例项目和适当的要求吗?更改 MainStampVc 或 MohrCollectionViewController 的颜色?? @Stefan 我实际处理的是我想从 mohrcollectionviewcontroller 更改我的 mainstampVc 的背景图像,它不是视图控制器而是 uiview! 【参考方案1】:

您可以在构造时将 UIViewController 引用传递给 MohrCollectionViewController(您应该调用此 MohrCollectionView 以避免混淆)。然后,每当您需要更新背景时,您都会在引用上调用相关函数。

class ViewController : UIViewController 
    ...
    override func viewDidLoad() 
        ...
        let view = addSubView(ViewName: "mohr")
        view?.vc = self
    
    func addSubView(ViewName: String) -> UIView?
    
        if let subview = Bundle.main.loadNibNamed(ViewName, owner: self, options: nil)?.first as? UIView 
            self.holderView.addSubview(subview);
            return subview
        
    
    return nil


class MohrCollectionView 

     func updateVcBackground() 
         vc?.updateBackground()
     
     var vc : ViewController? = nil

更简洁的方法是使用委托。委托使用协议来定义两个类之间的接口。

protocol UpdateBackgroundDelegate : class 
    func updateBackground()


class ViewController : UIViewController, UpdateBackgroundDelegate 
    ...
    override func viewDidLoad() 
        ...
        let view = addSubView(ViewName: "mohr")
        view?.updateBackgroundDelegate = self
    
    func updateBackground() 
        // update your background in this funcion
    


class MohrCollectionView 

     func updateVcBackground() 
         updateBackgroundDelegate?.updateBackground()
     
     var updateBackgroundDelegate : UpdateBackgroundDelegate? = nil

【讨论】:

非常感谢您的帮助,我完全忘记了代表团!但现在我遇到了问题,我更新了我的问题,你能帮我吗?【参考方案2】:

为了让代理工作,请执行以下操作:

    在集合视图类中首先声明委托

    protocol UpdateBackgroundDelegate : class 
    func updateBackground(imageURL: String)
    
    

    创建一个类似的变量

    var updateDelegate: UpdateBackgroundDelegate?
    

并将其粘贴到您要触发更改背景颜色的 collectionView 类下方

    在集合视图选择委托中,添加这行代码

    updateDelegate.updateBackground(imageUrl: yourUrl) 
    

    在必须进行颜色更改的视图中,创建您的 collectionView 实例并添加这行代码

    collectionView.updateDelegate = self 
    

    最后添加这个扩展

    class ViewController :UpdateBackgroundDelegate 
       func updateBackground(imageUrl: yourUrl) 
          //write code to load image from url
       
    
    

【讨论】:

以上是关于从另一个类访问 viewController 元素的主要内容,如果未能解决你的问题,请参考以下文章

从另一个类访问 UI 图像

在 Swift 中从另一个 ViewController 访问变量

从另一个类 c++ 访问 UI 元素

如何从另一个 UIView 类访问 UIControl 的值

如何从另一个 viewController 访问 tabBar 单击

快速从另一个访问 Viewcontroller 的实例