使用分段控制操作调用子视图控制器?

Calling child view controller using segmented control action?

我的父视图控制器中有两个子视图控制器,我想在分段控件中的值更改时调用它们,并希望通过子视图控制器设置父 imageView 的值。

protocol UserEdittedPhoto {
    func UserIsDone(image:UIImage)
}

class ControllerFinal:UIViewController, UserEdittedPhoto{

    func UserIsDone(imageEditted: UIImage){
        self.usedImage=imageEditted
        self.imageView.image=self.usedImage
    }

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

    @IBAction func segmentAction(sender:UISegmentedControl){

        if (segmentedControl.selectedSegmentIndex==0){

            performSegueWithIdentifier("EditIAm", sender: nil)
        }

        else if (segmentedControl.selectedSegmentIndex==1){

            performSegueWithIdentifier("EditIAm", sender: nil)
        }
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        if segue.identifier == "EditIAm"{

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let controller = storyboard.instantiateViewControllerWithIdentifier("ControllerEdit")
            self.presentViewController(controller, animated: true, completion: nil)

            let nextView = segue.destinationViewController as! ControllerEdit
            nextView.originalImage=self.imageView.image!
            nextView.delegate=self
        }

        else if segue.identifier == "FilterIAm"{

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let controller = storyboard.instantiateViewControllerWithIdentifier("ControllerFilters")
            self.presentViewController(controller, animated: true, completion: nil)

            let nextView = segue.destinationViewController as! ControllerFilters
            nextView.toBeFilter=self.imageView.image!
        }
    }

    class ControllerEdit:UIViewController{
        var delegate: UserEdittedPhoto? = nil
        if (delegate != nil){
        self.originalImage = UIImage(CIImage: CIImage(image: self.originalImage)!.exposureAdjustFilter(sliderValue.value)!)
        self.delegate!.UserIsDone(self.originalImage)
        print("I am Called!")
        }
    }

    class ControllerFilters:UIViewController{
        override func viewDidLoad() {
            print("SAHASHhqdwiuhiuhsaiuhsaiudhiuash")
            controllerFinal?.imageView.image=toBeFilter
            print("SAHASHhqdwiuhiuhsaiuhsaiudhiuash")
            super.viewDidLoad()
        }
}

在此函数中放置一个断点:

@IBAction func segmentAction(sender:UISegmentedControl){

    if (segmentedControl.selectedSegmentIndex==0){

        performSegueWithIdentifier("EditIAm", sender: nil)
    }

    else if (segmentedControl.selectedSegmentIndex==1){

        performSegueWithIdentifier("EditIAm", sender: nil)
    }
}

如果它没有被调用,那么您可能没有将它连接到 IB 中的操作(@IBAction 左侧的圆圈是否已填充?)

如果它被调用,那么确保 segue 名称是正确的——另外,修复 else if 中的名称,因为它看起来像你想要 "FilterIAm" 那里。

然后,在 prepareForSegue:... 中放置一个断点 -- 这会被调用吗?如果不是,请重新检查名称是否与 IB 中的名称相同。

编辑:基于评论

您的 prepareForSegue 不应创建 ViewController。目标视图控制器是作为执行 segue 并传递给此函数的结果创建的。

if segue.identifier == "EditIAm"{
    let nextView = segue.destinationViewController as! ControllerEdit
    nextView.originalImage=self.imageView.image!
    nextView.delegate=self
}

您不需要展示任何东西——目的地ViewController 将会展示。您可以设置它的任何变量(如您所愿)——这就是准备转场的意思。

更新

为了在下面的评论中反映我们的讨论,我认为您真的不需要 ContainersView Controllers 来管理您的自定义控件(编辑/过滤器)。这太过分了。

相反,我认为您应该创建 custom Views,然后将它们添加到主 Storyboard

然后当用户点击 Segmented Control 并向他们传递值时,您可以简单地 hide/show 您的自定义视图,例如:

CustomEditView.valueY = newValueY
CustomFiltersView.valueX = newValueX

关于:

I need to call it forcefully through segmentedControl action, so that my values in the childView be updated

然后你需要将目标 View Controllers 映射到局部变量,并在用户按下段时使用它们来更新目标 View Controller variables

我更新了代码并 "demo" 在我的回答中反映了这一点。
(请注意,我只是将随机 Strings 放在 labels 中以表明观点。)

现在完整的答案...


在您描述的 设置中,它基于 containersView Controllers 已经存在于 Storyboard 中。您绝对不需要再次显示它们(您可以删除 performSegueWithIdentifier 个调用)。

如果我没理解错的话,您只是想根据用户通过 Segmented Control.

选择的内容向用户显示不同的“控制器

有一些方法可以做到这一点,但最简单的方法是隐藏和显示 ControllerEdit / ControllerFilters View Controllerscontainers --通过更改 containers isHidden 变量状态。

像这样:

Storyboard 设置:

代码(基于):

import UIKit

protocol UpdateImageProtocol {
    func userIsDone(image: UIImage)
}

class ViewController: UIViewController, UpdateImageProtocol {

    @IBOutlet weak var imageView: UIImageView!

    @IBOutlet weak var changeImageContainer: UIView!
    var controllerEdit: ControllerEdit?

    @IBOutlet weak var applyFilterContainer: UIView!
    var controllerFilters: ControllerFilters?

    var image = UIImage(named: "hello")

    override func viewDidLoad() {
        super.viewDidLoad()
        userIsDone(image: image!)
    }

    func userIsDone(image: UIImage) {
        imageView.image = image
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "controllerEdit" {
            let nextView = segue.destination as! ControllerEdit
            nextView.delegate = self
            controllerEdit = nextView

        } else if segue.identifier == "controllerFilters" {
            let nextView = segue.destination as! ControllerFilters
            controllerFilters = nextView
        }
    }

    @IBAction func segmentAction(_ sender: UISegmentedControl) {
        if sender.selectedSegmentIndex == 0 {
            changeImageContainer.isHidden = false
            applyFilterContainer.isHidden = true

            controllerEdit?.customLabel.text = String(arc4random_uniform(999))

        } else {
            changeImageContainer.isHidden = true
            applyFilterContainer.isHidden = false

            controllerFilters?.customLabel.text = String(arc4random_uniform(999))
        }
    }
}

class ControllerEdit: UIViewController {

    @IBOutlet weak var customLabel: UILabel!

    var image = UIImage(named: "newHello")
    var delegate: UpdateImageProtocol?

    @IBAction func changeImage(sender: UIButton) {
        delegate?.userIsDone(image: image!)
    }
}

class ControllerFilters: UIViewController {

    @IBOutlet weak var customLabel: UILabel!

    // TODO
}