支持 iOS 8+, iPhone & iPad 通用
參考鏈接:
http://www.cnblogs.com/10-19-92/p/6215849.html
http://www.scianski.com/customizing-uipopover-with-uipopoverbackgroundview/
http://mobile.51cto.com/iphone-396554.htm
http://www.reibang.com/p/52dd6dec3e9b
部分屬性解釋
@property (nonatomic, assign) UIPopoverArrowDirection permittedArrowDirections;
箭頭方向.
@property (nullable, nonatomic, strong) UIView *sourceView;
sourceRect以這個(gè)view的左上角為原點(diǎn).
@property (nonatomic, assign) CGRect sourceRect;
指定箭頭所指區(qū)域的矩形框范圍, 以sourceview的左上角為坐標(biāo)原點(diǎn).
@property (nullable, nonatomic, strong) UIBarButtonItem *barButtonItem;
若有navigationController, 并且從'right/leftBarButtonItem'點(diǎn)擊后出現(xiàn)popover, 則可以把'right/leftBarButtonItem'看做上面說(shuō)的sourceView. 默認(rèn)箭頭指向up, 親測(cè)下來(lái)up是最合適的方向, 所以在這種情況下可以不設(shè)置箭頭方向.
注: 將當(dāng)前錨點(diǎn)設(shè)置為barButtonItem所在的位置. 在彈出窗口時(shí), 系統(tǒng)會(huì)自動(dòng)在barButtonItem的位置彈出. 如果需要修改彈出視圖和位置, 可以使用sourceView和sourceRect來(lái)替代這個(gè)屬性.
barButtonItem在設(shè)置之后,sourceView 和sourceRect將會(huì)失效
@property (nullable, nonatomic, copy) UIColor *backgroundColor;
背景色, 包含箭頭.
項(xiàng)目中的應(yīng)用
設(shè)計(jì)圖:
實(shí)現(xiàn)圖:
系統(tǒng)默認(rèn)的樣式是圓圓頭, 而不是設(shè)計(jì)圖中的尖尖頭. 所以這里要自定義樣式, 需要重寫UIPopoverBackgroundView
. 此處用了一個(gè)第三方GIKPopoverBackgroundView, 小伙伴們也可以自己實(shí)現(xiàn)哦.
彈出后, 會(huì)有一層淡淡的漸變黑的背景色, 這是系統(tǒng)自帶的.
基本配置
BSChildrenViewController *listVC = [[BSChildrenViewController alloc] init];
listVC.childrenList = self.childrenList;
CGFloat height = 40 + 44 * self.childrenList.count;
listVC.preferredContentSize = CGSizeMake(120, height);
listVC.modalPresentationStyle = UIModalPresentationPopover;
listVC.popoverPresentationController.barButtonItem = self.navigationItem.rightBarButtonItem;
listVC.popoverPresentationController.delegate = self;
listVC.popoverPresentationController.popoverBackgroundViewClass = [BSChildrenPopoverBackgroundView class];
[self presentViewController:listVC animated:YES completion:nil];
在 iPhone 中使用時(shí), 要實(shí)現(xiàn)下面的協(xié)議
#pragma mark - UIAdaptivePresentationControllerDelegate
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
彈出框?qū)崿F(xiàn)類 BSChildrenViewController.m 部分代碼
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 改變彈出框圓角.
self.view.superview.layer.cornerRadius = 5;
}
// 使 tableView 的大小為 寬度=120, 高度<=屏幕/3
- (CGSize)preferredContentSize {
if (self.presentingViewController && self.tableView != nil) {
CGSize tempSize = self.presentingViewController.view.bounds.size;
tempSize.width = 120;
CGSize size = [self.tableView sizeThatFits:tempSize];
return CGSizeMake(tempSize.width, MIN(SCREEN_HEIGHT/3, size.height));
} else {
return [self preferredContentSize];
}
}
- (void)setPreferredContentSize:(CGSize)preferredContentSize{
super.preferredContentSize = preferredContentSize;
}
注: 若彈出動(dòng)作是在 [tableView:didSelectRowAtIndexPath:] 中觸發(fā)的, 則
// 此處要NO, 否則 popover 彈框有延遲.
[tableView deselectRowAtIndexPath:indexPath animated:NO];