Запустить метод в UIViewController из его представления

У меня есть UIViewController с UIView который содержит UIButton . Я хочу вызвать метод в UIViewController при событии нажатия кнопки.
Сохранение ссылки UIViewController , похоже, не очень хорошая идея, как в следующей ссылке: « Получить UIViewController из UIView?

Поэтому я хочу добиться этого, используя делегат. Любой намек на то, как этого добиться?

7 Solutions collect form web for “Запустить метод в UIViewController из его представления”

Вы можете сделать что-то подобное

CustomView.h

 #import <UIKit/UIKit.h> @protocol CustomViewDelegate <NSObject> -(void)didButtonPressed; @end @interface CustomView : UIView @property (assign) id<CustomViewDelegate> delegate; @end 

CustomView.m

 #import "CustomView.h" @implementation CustomView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.backgroundColor = [UIColor whiteColor]; //[self addSubview:titleLbl]; UIButton *button= [UIButton buttonWithType:UIButtonTypeRoundedRect]; button.frame = CGRectMake(100, 100, 100, 50); [button addTarget:self.delegate action:@selector(didButtonPressed) forControlEvents:UIControlEventTouchUpInside]; [button setTitle:@"pressMe" forState:UIControlStateNormal]; [self addSubview:button]; } return self; } 

в вашем ViewController.m

 -(void)loadView { [super loadView]; CustomView *view = [[CustomView alloc]initWithFrame:self.view.bounds]; view.delegate = self; [self.view addSubview:view]; } 

Я предполагаю, что вы ожидали чего-то более фундаментального, а затем просто передали действие кнопки контроллеру. Я всегда слежу за шаблоном MVC в случае совместной работы модели / представления / контроллера. Он разрешает вашу проблему и многие другие. И я хочу поделиться своим опытом.

  1. Отдельный контроллер из представления и модели: не помещайте всю «бизнес-логику» в классы, связанные с просмотром; это делает код очень непригодным. Создайте классы контроллеров для размещения этого кода, но убедитесь, что классы контроллера не делают слишком много предположений о презентации.
  2. Определите API обратного вызова с помощью @protocol , используя @optional если не все методы необходимы.
  3. Для представления определите протокол, например <view class name>Protocol (пример NewsViewProtocol). Для контроллера определите делегат как <view class name>Delegate (пример NewsViewDelegate) и dataSource, например <view class name>DataSource (пример NewsViewDataSource). Храните все эти @protocols в одном отдельном файле с именем <view class name>Protocol.h (пример NewsViewProtocol.h)

Краткий пример:

Содержание NewsView.h

 // // NewsView.h @interface NewsView : UIView <NewsViewProtocol> { @protected NSObject* delegate_; NSObject* dataSource_; } @end 

Содержание NewsController.h и .m

 // // NewsController.h @interface NewsController : UIViewController <NewsViewDataSource, NewsViewDelegate> { } @property (nonatomic, weak) UIView<NewsViewProtocol>* customView; @end @implementation NewsController - (void)viewDidLoad { [super viewDidLoad]; self.customView = (UIView<NewsViewProtocol>*)self.view; [self.customView setDelegate:self]; [self.customView setDataSource:self]; } @end 

Содержание NewsViewProtocol.h

 // // NewsViewProtocol.h @protocol NewsViewProtocol; @protocol NewsViewDelegate<NSObject> @optional - (void)someAction; - (void)newsView:(UIView<NewsViewProtocol>*)newsView didSelectItemAtIndexPath:(NSIndexPath *)indexPath; @end @protocol NewsViewDataSource<NSObject> @required - (id)newsView:(UIView<NewsViewProtocol>*)newsView itemAtIndexPath:(NSIndexPath *)indexPath; - (NSInteger)numberOfItemsInNewsView:(UIView<NewsViewProtocol>*)newsView section:(NSInteger)section; - (BOOL)newsView:(UIView<NewsViewProtocol>*)newsView shouldDisplaySection:(NSInteger)section; @end @protocol NewsViewProtocol<NSObject> @required //Never retain delegate instance into implementation of this method - (void)setDelegate:(NSObject<NewsViewDelegate>*)delegate; //Never retain delegate instance into implementation of this method - (void)setDataSource:(NSObject<NewsViewDataSource>*)dataSource; - (void)reload; @end 

Вы можете считать, что он избыточен. В простом контроллере просмотра YES. Но если вы разрабатываете очень сложный экран с огромным количеством данных, он дает вам некоторые преимущества:

  • Помогает вам отделить ответственность между представлением и контроллером.
  • Сохраняет ваш код.
  • Делает код более многоразовым.

Для этого была создана цепочка ответчиков. Когда вы добавляете цель в свою кнопку, просто поставьте nil для цели:

 [mySpecialButton addTarget:nil action:@selector(mySpecialButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; 

Цель nil основном означает «отправить mySpecialButtonTapped: любому объекту в цепочке ответчиков, который сможет обработать его».

Теперь вы можете обработать этот селектор в любой точке цепи ответчика, который включает в себя собственно кнопку, ее содержащий вид, его содержащий контроллер представлений, UIApplication и, наконец, AppDelegate. Просто поместите этот метод в объект, наиболее подходящий для ваших нужд:

 - (void)mySpecialButtonTapped:(id)sender { NSLog("My special button was tapped!"); } 

Вы не нуждаетесь в делегатах или блоках обратного вызова (как в принятом ответе), если вы просто хотите вывести сообщение вверх.

Жизнь проста в xCode.

В самом начале убедитесь, что ваш xib View (тот, у которого есть кнопка внутри него) связан с правильным классом ViewController. Каким может быть класс ViewController по умолчанию, который поставляется с новым проектом или вашим обычным.

После этого здесь приходит волшебный трюк! Отделите свой вид на 2 панели. Цель состоит в том, чтобы увидеть ваш xib и ваш код viewController (файл .m). Теперь нажмите клавишу управления на клавиатуре и перетащите свой UIButton в код. Выберите IBAction. Он будет генерировать то, что вы можете назвать «слушателем» на другом языке. Перейдите к основному коду вашего контроллера просмотра и выполните метод!

Легко! Повеселись 🙂

Вам действительно не нужны делегаты для этого – как предполагается использовать UIButtons. Просто нажмите «Control» и перетащите его с помощью кнопки .m-файла для вашего UIViewController. Это создаст новый метод. Оттуда вы можете сделать вызов метода, который вы написали, или просто скопировать-вставить то, что у вас есть, в новый метод.

Вы можете попробовать следующее:

 [yourButton addTarget:self action:@selector(yourButtonAction:) forControlEvents:UIControlEventTouchUpInside]; 

И в вашем селекторе укажите действие

 - (IBAction)yourButtonAction:(id)sender { //Action to perform } 

Чтобы добавить кнопку программно, в myViewController.m

 UIView *yourView = [[UIView alloc] init]; UIButton *yourButton = [[UIButton alloc] initWithFrame:CGRectMake(0,0,100,21)]; [yourButton addTarget:self action:@selector(yourMethod) forControlEvents:UIControlEventTouchDown]; [yourView addSubview:yourButton]; 

Больше информации здесь .

  • UIViewController Animation ios?
  • performSegueWithIdentifier не будет вызывать просмотр
  • Разрешить UIKit обрабатывать вращение устройства в OpenGLES 1.1 - это на самом деле все медленнее, и если да, то при каких обстоятельствах?
  • Изменить название UINavigationController при изменении UIPageViewController
  • Как открыть приложение для фотографий из UIViewController?
  • Многоуровневые контроллеры детского просмотра, где делегирование становится кошмаром - как они должны общаться друг с другом?
  • NSInternalInconsistencyException - Не удалось загрузить NIB в комплекте
  • Есть ли способ просмотреть UIViewController за другим UIViewController, не входя в окно AppDelegate?
  • Прокрутка вверх, когда вы нажимаете строку состояния
  • Xcode 7 - Xcode 8 Предупреждения о препятствиях раскадровки
  • Пользовательский интерфейс блокируется при нажатии контроллера просмотра на контроллер навигации
  • Внешний вид таблицы внутри, внутри viewcontroller. Лучший способ сделать это?
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.