Вызов контроллера дочернего представления с использованием действия сегментированного управления?

У меня есть два дочерних контроллера представления в моем родительском контроллере представления, я хочу вызвать их при изменении значения в сегментированном элементе управления и хочу установить значение родительского 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()
        }
}

person Zuhaib Rasheed    schedule 25.03.2017    source источник
comment
Пожалуйста, проверьте это. @обратная косая черта-f   -  person Zuhaib Rasheed    schedule 25.03.2017
comment
С какой проблемой вы столкнулись?   -  person Partho Biswas    schedule 25.03.2017
comment
Я столкнулся с проблемой при представлении контроллера дочернего представления в сегментированном управляющем действии. @ParthoBiswas   -  person Zuhaib Rasheed    schedule 25.03.2017


Ответы (2)


ОБНОВЛЕНИЕ

Чтобы отразить наше обсуждение в комментариях ниже, я не думаю, что вам действительно нужны Containers и View Controllers для управления вашими пользовательскими элементами управления (Edit / Filters). Это перебор.

Вместо этого, я думаю, вам следует создать custom Views, а затем добавить их в свой основной Storyboard.

Затем вы можете просто скрыть/показать свои пользовательские представления, когда пользователи нажимают на Segmented Control, а также передавать им значения, например:

CustomEditView.valueY = newValueY
CustomFiltersView.valueX = newValueX

Касательно:

Мне нужно принудительно вызвать его через действие segmentedControl, чтобы мои значения в дочернем представлении обновлялись.

Затем вам нужно сопоставить цель View Controllers с локальными переменными и использовать их для обновления цели View Controller variables, когда пользователи нажимают на сегменты.

Я обновил код и «демонстрацию» в своем ответе, чтобы отразить это.
(Обратите внимание, что я просто добавляю случайные Strings в labels, чтобы подчеркнуть.)

Теперь полный ответ...


В настройке вы описали в ваш другой вопрос, основанный на containers, View Controllers уже есть, в Storyboard. Вам совершенно не нужно предъявлять их повторно (вы можете удалить performSegueWithIdentifier звонки).

Если я правильно понял, вы просто хотите показать пользователю разные «контроллеры» в зависимости от того, что он выберет через Segmented Control.

Для этого есть несколько способов, но самый простой — скрыть и показать containers из ControllerEdit / ControllerFilters View Controllers -- путем изменения состояния переменной 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
}
person backslash-f    schedule 25.03.2017
comment
У меня есть основные изменения для изображений в представлении 1 и некоторые фильтры в представлении 2. Это хороший подход, чтобы просто показать и скрыть дочерний вид? @обратная косая черта-f - person Zuhaib Rasheed; 25.03.2017
comment
Мне нужно передавать обновленные значения из segue в childviewController каждый раз, когда я нажимаю сегментированный элемент управления, но он вызывается только один раз в начале, а затем показывает и прячет себя. @backslah-f - person Zuhaib Rasheed; 26.03.2017
comment
Это сработало бы, но лично я не думаю, что это очень хороший подход с точки зрения архитектуры... Не похоже, что вам действительно нужны контроллеры представления для обработки ваших пользовательских контроллеров. Это перебор. Было бы лучше создать пользовательские представления и просто показать/скрыть эти пользовательские представления. Я написал учебник по этому поводу: /, посмотри. Я обновлю свой ответ этой информацией. - person backslash-f; 26.03.2017
comment
Что касается того, что мне нужно передавать обновленные значения из segue в childviewController каждый раз, когда я нажимаю сегментированный элемент управления, это будут переменные в ваших пользовательских представлениях. Затем каждый раз, когда пользователь нажимает сегментированный элемент управления, вы должны, например: editView.customValue = значение / filterView.customValue = значение. - person backslash-f; 26.03.2017
comment
Я не думаю, что понял это, я имею в виду, что я должен передавать значение imageView каждый раз, когда пользователь нажимает на segmentedControl, и я делаю это через переход, но он вызывается только один раз, а не каждый раз, когда я нажимаю на segmentedControl. @обратная косая черта-f - person Zuhaib Rasheed; 26.03.2017
comment
Какую часть вы не поняли? - person backslash-f; 26.03.2017
comment
Где обновить значение переменной childView? В переходе или в контроллере сегментированных действий? Если в действии segmentedController, то как? @обратная косая черта-f - person Zuhaib Rasheed; 26.03.2017
comment
Если вы собираетесь придерживаться текущей настройки (контейнеры/контроллеры представлений), обновите значение переменных childView в функции prepareForSegue. Если вы собираетесь использовать настраиваемые представления, обновите настраиваемые переменные представления в сегментированном элементе управления. - person backslash-f; 26.03.2017
comment
Я пока придерживаюсь своей настройки (Container/ViewController), сэр, это то, что я делаю, обновляя значения childVariables через функцию перехода, но переход вызывается только один раз. Мне нужно принудительно вызвать его через действие segmentedControl, чтобы мои значения в дочернем представлении обновлялись. мне нужно решение для этого. Заранее большое спасибо, вы мне уже очень помогаете. @обратная косая черта-f - person Zuhaib Rasheed; 26.03.2017
comment
Пока нет на гитхабе, если скажете, загружу завтра. - person Zuhaib Rasheed; 26.03.2017
comment
Я понимаю. В этом случае вам нужно сопоставить целевые контроллеры представления в prepareForSegue с локальными переменными и обновить их, когда пользователи нажимают на сегмент. Я обновил свой ответ, показав, как это сделать, посмотрите. - person backslash-f; 26.03.2017
comment
Привет! Это решило проблему, большое спасибо. @обратная косая черта-f - person Zuhaib Rasheed; 26.03.2017

Поставьте точку останова в этой функции:

@IBAction func segmentAction(sender:UISegmentedControl){

    if (segmentedControl.selectedSegmentIndex==0){

        performSegueWithIdentifier("EditIAm", sender: nil)
    }

    else if (segmentedControl.selectedSegmentIndex==1){

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

Если он не вызывается, то вы, вероятно, не подключили его к действию в IB (круг слева от @IBAction заполнен?)

Если он вызывается, убедитесь, что имена переходов верны, а также исправьте имя в else if, потому что похоже, что вам нужен «FilterIAm».

Затем поставьте точку останова в prepareForSegue:... -- это вызывается? Если нет, перепроверьте, имена такие же, как в ИБ.

РЕДАКТИРОВАТЬ: на основе комментария

Ваш prepareForSegue не должен создавать ViewController. Целевой контроллер представления создается в результате выполнения перехода и передается этой функции.

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

Вам не нужно ничего представлять — будет представлен targetViewController. Вы можете установить любую его переменную (как у вас) - вот что подразумевается под подготовкой к переходу.

person Lou Franco    schedule 25.03.2017
comment
не могли бы вы проверить функцию prepareforsegue, я думаю, что ошибка в этой функции, я хочу представить childviewController и передать ему значение. Это правильно? @ЛуФранко - person Zuhaib Rasheed; 25.03.2017