#ios #swift #uicontainerview
#iOS #swift #UIContainerView
Вопрос:
У меня есть представление контейнера внутри контроллера представления. Когда пользователь нажимает кнопку, должно отображаться представление контейнера, но текст в представлении контейнера зависит от того, какую кнопку нажал пользователь. Для этого мне нужно обновить представление контейнера, но я не уверен, как это сделать.
Это мой код представления контейнера:
override func viewDidLoad() {
super.viewDidLoad()
Cancel_Button.hidden = true
Save_Button.hidden = true
let Storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let ViewController: View = Storyboard.instantiateViewControllerWithIdentifier("View") as! View
Title_String = ViewController.String
Title_Label.text = Title_String
}
И это код в моем контроллере представления:
@IBOutlet var View_Controller_Popup: UIView!
var String = String()
override func viewDidLoad() {
super.viewDidLoad()
View_Controller_Popup.hidden = true
}
@IBAction func Button_Pressed(sender: AnyObject) {
let Storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let ViewController: ContainerView = Storyboard.instantiateViewControllerWithIdentifier("Container") as! ContainerView
self.String = "Specific Title"
ViewController.Title_String = self.String
self.View_Controller_Popup.hidden = false
}
Итак, как мне перезагрузить представление контейнера, чтобы при нажатии кнопки отображалось представление контейнера с текстом метки на основе нажатой кнопки.
Обновить:
Поскольку некоторые люди не могут понять проблему, с которой я столкнулся, я перефразирую проблему с изображениями.
Это мое мнение:
Изображения были удалены
Как вы можете видеть, здесь много кнопок (со значками). Когда пользователь нажимает кнопку, я хочу, чтобы отображалось представление контейнера с информацией:
Таким образом, для каждой кнопки текст метки должен быть разным. Но в настоящее время в приложении строка пуста, и поэтому текст метки пуст:
Я считаю, что это связано с тем, что я не обновляю код в представлении контейнера, и поэтому строка по-прежнему пуста.
Итак, проблема в том, что в представлении контейнера неправильно отображается заголовок заголовка, и я думаю, что это связано с тем, что не обновляется представление контейнера, но на самом деле я не знаю, как обновить представление контейнера.
Комментарии:
1. Если вы используете раскадровку, вы можете настроить свой контроллер представления с помощью встроенного перехода. В вашем содержащем ViewController вы можете получить ссылку на содержащийся в нем контроллер представления
prepareForSegue
и искать переход к встраиванию. После сохранения ссылки в свойстве вы можете вызывать функции для нее в любое время, когда вам нужно.2. Я использую раскадровку, не могли бы вы показать мне, как это сделать в коде?
Ответ №1:
попробуйте использовать протокол делегирования ваш containerView должен расширять родительский протокол делегирования и просто реализовать функцию с аргументами func updateContent(id: Int)
protocol ContentDelegate {
func updateContent(id: Int)
}
class ParentViewController: UIViewController {
var delegate: ContentDelegate?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "containerController") {
let containerVC = segue.destination as! ChildContainerViewController
self.delegate = containerVC
}
}
}
class ChildContainerViewController: UIViewController, ContentDelegate {
func updateContent(id: Int) {
// your code
}
}
Комментарии:
1. Как я могу это сделать, если я не использую раскадровку? В деталях, как обойтись
containerVC
безprepare(foor segue:)
.
Ответ №2:
Я нашел решения для проблемы аналогичного типа, когда я использую представление контейнера для отображения определенного выбора пользователя, связанного с данными, в табличном представлении.
- MainViewController как базовое представление, которое содержит представление контейнера, которое является pageViewController.
- MainViewController имеет 3 segmentedControl с 3 сегментами.
- Когда пользователь выбирает новый сегмент, мне нужно обновить данные внутри представления контейнера, чтобы отобразить данные, связанные с сегментом.
В основном обновление представления контейнера из базового ViewController.
После долгих поисков найдено решение :
-
По сути, представление контейнера — это childViewControllers внутри базовых ViewControllers.
-
Нам просто нужно найти правильные childViewControllers для обновления данных.
Если у вас есть только в представлении contianer :
let vc = self.childViewControllers[0] as! PageViewController
vc.segment = selectedSegment
vc.viewWillAppear(true)
Или, если у вас есть несколько childViewControllers :
for controller in self.childViewControllers {
if controller.isKind(of: PageViewController.self) {
let vc = controller as! PageViewController
vc.segment = selectedSegment
vc.viewWillAppear(true)
}
}
Ответ №3:
Вот как я это сделал, используя Swift 5. Вы в основном перебираете дочерние элементы, чтобы получить ссылку на нужный VC. Это работает независимо от того, есть ли только один или несколько дочерних контроллеров представления.
if let vc = children.filter({$0 is ContainerViewController}).first as? ContainerViewController {
vc.setupView()
}
Комментарии:
1. Лучшее и простое решение.
Ответ №4:
Я не совсем уверен, о чем вы спрашиваете, но я попытаюсь ответить. Дайте мне знать, если я неправильно понимаю.
Ключевым моментом здесь является только ваша архитектура. Я бы предложил использовать уникальные методы действий для каждой кнопки. Это будет выглядеть примерно так:
@IBAction func ButtonOnePressed(sender: AnyObject) {
initializeContainerView(withTitle: "Button One Title")
}
@IBAction func ButtonTwoPressed(sender: AnyObject) {
initializeContainerView(withTitle: "Button Two Title")
}
func initializeContainerView(withTitle title: String) {
let Storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let ViewController: ContainerView = Storyboard.instantiateViewControllerWithIdentifier("Container") as! ContainerView
ViewController.Title_String = title
self.View_Controller_Popup.hidden = false
}
Однако, если вы предпочитаете / требуете использовать один и тот же метод действий между кнопками, добавьте теги к своим кнопкам UIButton.tag
. Затем просто используйте оператор switch в вашем методе действия, чтобы проверить sender.tag и запустить код для этого случая. Это будет выглядеть примерно так:
@IBAction func Button_Pressed(sender: AnyObject) {
switch sender.tag {
case buttonOneTagValue:
initializeContainerView(withTitle: "Button One Title")
case buttonTwoTagValue:
initializeContainerView(withTitle: "Button Two Title")
default:
break
}
func initializeContainerView(withTitle title: String) {
let Storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let ViewController: ContainerView = Storyboard.instantiateViewControllerWithIdentifier("Container") as! ContainerView
ViewController.Title_String = title
self.View_Controller_Popup.hidden = false
}
Комментарии:
1. Я пробовал ваш код и другой код, но мне кажется, что вы неправильно поняли вопрос. Смотрите мой обновленный вопрос.
2. Вы можете попробовать обновить представление контейнера с помощью ViewController .view.setNeedsDisplay() Вы можете поместить эту строку в
initializeContainerView
качестве последней строки.3. Быстро, можете ли вы жестко запрограммировать значение UILabel.text, чтобы увидеть, является ли оно непустым?
4. Кажется, все работает нормально. Я добавил печать в представлении контейнера, и она печатает пустую строку до и после setNeedsDisplay() .
5. Я могу отправить вам файлы, чтобы узнать, можете ли вы найти проблему, но я действительно не понимаю, почему она не работает.
Ответ №5:
В вашем initializeContainerView
методе измените:
self.Day_Period_String = title
ViewController.Title_String = self.Day_Period_String
Для:
ViewController.Title_String = title
И в вашем контроллере представления контейнера удалите:
Title_String = ViewController.Day_Period_String
Наконец, измените эту строку:
var Title_String = String()
Для:
var Title_String: String!
Если это не сработает, я попрошу вас добавить несколько строк печати. К сожалению, я обновился до XCode 8 (и, следовательно, Swift 3), поэтому не могу запустить ваш код.
Комментарии:
1. Хорошо, я добавил несколько отпечатков вокруг кода, и кажется, что текст метки задается правильно, но не отображается. Таким образом, строка заголовка не пуста, текст метки не пуст, но при добавлении этого в текст: .text = Title_String «Testing» отображается только «Тестирование». Итак, ярлык обновляется неправильно?
2. Хм. Вот почему я предлагал использовать setNeedsDisplay, поскольку казалось, что ваши данные установлены правильно, поскольку это должно заставить пользовательский интерфейс обновляться. Может быть, ваша ширина UILabel слишком мала и, следовательно, не отображает текст? Один из способов подтвердить это — напечатать ширину UILabel или вы можете добавить строку после инициализации и обновления в текст, чтобы убедиться, что размер соответствует тексту: Title_Label.sizeToFit()
3. Но он отображает текст, просто не тот текст, который я хочу, но при печати метки на консоли он печатает то, что я хочу, чтобы он печатал.
4. Какой текст отображается в UILabel представления контейнера? У вас есть какой-то текст по умолчанию, добавленный в раскадровку или что-то в этом роде?
5. Если я сделаю это: self. Title_Label.text = «Текст здесь» Здесь отображается текст. Если я сделаю это: self. Title_Label.text = self. Title_String «Текст здесь» здесь отображается только текст.