Как использовать Storyboard для создания popover, который может использоваться в коде?
Я создаю набор форм, каждый из которых содержит несколько полей. Некоторые из полей UITextField
, которые будут отображать дату. Я создал новый класс под названием DatePickerTextField
, потомок UITextField
. Когда a DatePickerTextField
используется, я хотел бы, чтобы элемент управления UIDatePicker
отображался в popover
.
Мой вопрос: как использовать раскадровку для реализации popover
? Я могу сделать segue, когда на сцене есть конкретный видимый элемент управления. Но как мне представить общий popover
в сцене, который я могу подключить к любому экземпляру DatePickerTextField
, который станет активным?
Ответы
Ответ 1
Вы можете создать segue, который не связан с каким-либо элементом управления, но я не думаю, что был бы способ указать опорную точку для popover из кода. Другой вариант - создать ViewController, который не связан с каким-либо сегментом. При редактировании раскадровки создайте ViewController, который будет помещен в popover, выберите его и перейдите в панель "Утилиты" → "Attributes Inspector". Задайте размер Freeform, Строка состояния - Нет, укажите уникальный идентификатор, который будет использоваться для создания экземпляра ViewController из кода. Теперь вы можете изменить размер ViewController, выбрав его "Просмотр" и перейдите в панель "Утилиты" → "Инспектор размеров".
После этого вы можете создать popover из кода:
- (IBAction)buttonPressed:(id)sender {
UIView *anchor = sender;
UIViewController *viewControllerForPopover =
[self.storyboard instantiateViewControllerWithIdentifier:@"yourIdentifier"];
popover = [[UIPopoverController alloc]
initWithContentViewController:viewControllerForPopover];
[popover presentPopoverFromRect:anchor.frame
inView:anchor.superview
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
Одно из предостережений заключается в том, что вам нужно сохранить ссылку на popover как ivar вашего класса, иначе он сработает, потому что UIPopoverController будет освобожден и освобожден после buttonPressed
:
@interface MyViewController : UIViewController {
// ...
UIPopoverController *popover;
// ...
}
Ответ 2
Итак, у меня была аналогичная проблема, и в случае, если другие могут принести пользу, я решил, что я поделюсь ею, так как я так сильно выигрываю от stackoverflow.
Это решение позволяет вам установить привязку настраиваемого сегмента popover. Это также позволяет настроить segue как модальный или нет (я не мог найти способ предотвратить segue, уменьшив внешний контекст, поэтому, если кто-то знает, как это сделать, мне было бы интересно услышать его); это достигается установкой представлений пересылки для контроллера popover. Я также добавил возможность указать пользовательский вид, а не представление источника viewcontroller (так как мне нужна эта емкость); эта часть не имеет решающего значения для решения.
DynamicPopoverSegue.h
@interface DynamicPopoverSegue : UIStoryboardPopoverSegue
@property BOOL isModal;
@property UIView* sourceView;
@property CGRect anchor;
@end
DynamicPopoverSegue.m
@implementation DynamicPopoverSegue
- (void)perform
{
if (!self.popoverController.popoverVisible)
{
UIViewController* dst = (UIViewController*)self.destinationViewController;
UIViewController* src = (UIViewController*)self.sourceViewController;
UIView* inView = _sourceView ? _sourceView : src.view;
self.popoverController.contentViewController = dst;
if (!_isModal)
{
[self.popoverController setPassthroughViews:[[NSArray alloc] initWithObjects:inView, nil]];
}
[self.popoverController presentPopoverFromRect:_anchor
inView:inView
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
}
@end
Затем вы просто установили свой segue в "Custom" в раскадровке и установите класс segue в "DynamicPopoverSegue". В моем случае, поскольку я хотел связать его с динамическими слоями в представлении, я не мог установить привязку, поэтому я создал segue, щелкнув элемент управления, щелкнув значок значка в панели под моим контроллером представления, на контроллер представления, на котором я был используя для представления popupover.
Чтобы вызвать popper segue:
[self performSegueWithIdentifier:@"MyPopoverSegue" sender:self];
И чтобы настроить popover segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"MyPopoverSegue"])
{
DynamicPopoverSegue* popoverSegue = (DynamicPopoverSegue*)segue;
// set the anchor to wherever you want it to be
popoverSegue.anchor = _destinationFrame;
}
}
Ответ 3
- (IBAction)pressItemChooseOprateRoom:(id)sender {
if (isPad){
// UIView *anchor = sender;
UIViewController *viewControllerForPopover =
[self.storyboard instantiateViewControllerWithIdentifier:@"OperateRoomList"];
_myPopover = [[UIPopoverController alloc]
initWithContentViewController:viewControllerForPopover];
CGRect rc=[self getBarItemRc:sender];
[_myPopover presentPopoverFromRect:rc
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[MLControl shared].popover =self;
// [self perfformSegueWithIdentifier:SEGUE_POP_OPERATEROOM sender:self];
}else{
[self iphoneOpenOperateRoomList];
/* [self performSegueWithIdentifier:@"iPhonePushOperateRoom" sender:self];
*/
}
}
-(void)iphoneOpenOperateRoomList{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"OperateRoomList"];
// if (!index.showTabBar) {
// vc.hidesBottomBarWhenPushed = YES;
// }
[self.navigationController pushViewController:vc animated:YES];
}
Ответ 4
Просто использовал ответ от Jonnywho для моего проекта SWIFT. Если вам это нужно:
Здесь версия SWIFT:
let anchor: UIView = sender
var viewControllerForPopover = self.storyboard?.instantiateViewControllerWithIdentifier("GameAboutViewController") as! UIViewController?
let popover = UIPopoverController(contentViewController: viewControllerForPopover!)
popover.presentPopoverFromRect(anchor.frame, inView: anchor, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)