Я новичок в Swift и Xcode. Я создаю приложение «Финансовые расходы» для iOS.
В моем первом контроллере представления я создал выход для ссылки для метки с именем costNum.
В моем втором контроллере представления у меня есть функция для кнопки под названием «Добавить расходы». При щелчке по нему мне нужно обновить переменную costNum суммой расходов.
Как лучше всего это сделать? Я создал объект первого класса контроллера представления и получил к нему доступ как «firstviewcontroller.expenseNum», но это создаст новый экземпляр класса, и мне нужно, чтобы он был одним и тем же экземпляром, чтобы он мог непрерывно добавлять к той же переменной. Спасибо за помощь!
Вам нужен делегат
protocol SendManager {
func send(str:String)
}
Во-первых
class FirstVc:UIViewcontroller , SendManager {
func send(str:string) {
self.expenseNum.text = str
}
}
когда вы представляете SecondVc
let sec = SecondVc()
sec.delegate = self
// настоящее время
Во второй
class SecondVc:UIViewcontroller {
var delegate:SendManager?
@IBAction func btnClicked(_ sender:UIButton) {
delegate?.send(str:"value")
}
}
// установка делегата
в viewDidLoad
SecondVc
if let first = self.tabBarController.viewControllers[0] as? FirstVc {
self.delegate = first
}
Вы определяете протокол в первом контроллере представления или во втором?
везде, где он будет доступен над объявлением класса
Итак, я определил протокол в верхней части файла с первым контроллером представления в нем. Это верно? Когда вы говорите «когда вы представляете secondVc», где вы размещаете этот код?
да, правильно ---- как вы показываете secondVC present / segue / push?
Не совсем уверен ... Я работаю с приложением с вкладками. Первая вкладка - это первый контроллер представления, а вторая вкладка - второй контроллер представления.
Большое спасибо! Кроме того, после редактирования «let sec = SecondVc () sec.delegate = self» все еще существует. Нужно ли это где-то размещать или это делает оператор if?
это было для segue, present / push ,,, но в вашем случае оператор if заменяет его
небольшое улучшение по сравнению с ответом 1 сделайте класс протокола специфичным, как этот протокол SendManager: class {func send (str: String)} 2. объявите слабый делегат, чтобы спасти его от сохранения цикла памяти weak var делегат: SendManager?
Есть несколько способов передать данные с ViewController2
на другой ViewController1
.
Лучший способ здесь - Делегаты протокола
Пожалуйста, следуйте инструкциям ниже, чтобы передать данные
В вашем SecondViewController
, откуда вы хотите отправить данные обратно, объявите протокол в верхней части объявления класса
protocol SendDataBack: class {
func sendDataFromSecondVCtoFirstVC(myValue: String)
}
Теперь в class
объявите объект вашего протокола в том же ViewController
.
weak var myDelegateObj: SendDataBack?
И теперь в действии кнопки Добавить расходы просто вызовите метод делегата
myDelegateObj?.sendDataFromSecondVCtoFirstVC(myValue: yourValue)
Теперь перейдите к своему первому ViewController
место, откуда вы нажали / представили SecondViewController, вы должны были взять объект SecondVC, чтобы нажать, чтобы нажать с первого
if let secondVC = (UIStoryboard.init(name: "Main", bundle: nil)).instantiateViewController(withIdentifier: "secondVCID") as? SecondViewController {
vc?.myDelegateObj = self
self.navigationController?.pushViewController(secondVC, animated: true)
**OR**
self.present(secondVC, animated: true, completion: nil)
}
now in your FirstViewController make an extension of FirstViewVC
extension FirstViewController: SendDataBack {
func sendDataFromSecondVCtoFirstVC(myValue: String) {
}
}
вы должны сделать слабый делегат, чтобы спасти его от сохранения цикла памяти и от утечек памяти !! как этот слабый var myDelegateObj: SendDataBack?
Я думаю, вы можете сделать переменную в своих свойствах во втором ViewController (до метода viewDidLoad)
var delegate: FirstViewController? = nil
и использовать из свойств первого контроллера представления в любом месте второго контроллера представления.
delegate!.mainTableView.alpha=1.0
//for example access to a tableView in first view controller
Самый простой способ добиться этого - использовать общедоступную переменную. Добавьте в проект новый файл Swift, назовите его Globals. Объявите общедоступную переменную в Globals.swift следующим образом:
public var theValue: Int = 0
Установите его необходимое значение в первом ViewController, и вы обнаружите, что можете легко прочитать его во втором.
Где вы размещаете протокол SendManager {func send (str: String)}