前言
最近項目中很多地方有一個相同的需求鞍历,那就是點擊一個按鈕的時候在按鈕的某一個方向彈出一個視圖位谋,這個視圖需要帶有一個箭頭指向,就像下圖一樣堰燎。要實現(xiàn)這個功能掏父,就要用到UIPopoverPresentationController這個類了。
簡介
一個帶有箭頭的彈出視圖從出現(xiàn)到消失的整個過程秆剪,都是UIPopoverPresentationController類的實例在管理赊淑,UIPopoverPresentationController類的實例管理著彈出視圖的外形和其它的一些性質(zhì)。
我們不需要直接去創(chuàng)建這個類的對象仅讽,當(dāng)我們把這個彈出視圖對應(yīng)的視圖控制器的modalPresentationStyle
屬性設(shè)置為UIModalPresentationPopover
時陶缺,viewcontroller就會擁有一個popoverPresentationController
屬性,它就是UIPopoverPresentationController類型的洁灵,用它來管理這個彈出視圖的外形和其它一些性質(zhì)饱岸。
UIPopoverPresentationControllerDelegate
UIPopoverPresentationControllerDelegate對象會通知它的delegate整個彈出視圖從彈出到消失的整個過程掺出。下面是其主要的API:
通知delegate視圖將要呈現(xiàn):
- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController;
詢問delegate視圖是否應(yīng)該消失
- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController;
通知delegate視圖已經(jīng)消失
- (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController;
相關(guān)屬性
- backgroundColor
上圖中設(shè)置的backgroundColor是紅色,上圖中彈出視圖是由兩部分疊加的苫费,一部分是上面的viewcontroller的View汤锨,其背景色是黃色,還有一部分是承載viewcontroller的View的視圖百框,這個視圖是由viewcontroller的popoverPresentationController對象來管理的闲礼。 - passthroughViews
這是一個數(shù)組,里面裝著視圖铐维,一般情況下在彈出視圖可見的情況下柬泽,點擊界面上其他視圖是無效的,這會導(dǎo)致彈出視圖消失嫁蛇,但是這個數(shù)組中的視圖不會這樣锨并,在彈出視圖可見的情況下仍然可以點擊這些視圖。 - canOverlapSourceViewRect
這是一個布爾值睬棚,說明彈出視圖是否可以和sourceRect重疊第煮。 - sourceView
這個屬性其實就是要指出彈出視圖的箭頭要指向哪個視圖。 - permittedArrowDirections
這個屬性要確定彈出視圖的箭頭的方法闸拿,它是一個枚舉值空盼,上圖中設(shè)置的箭頭方向是左邊书幕。 - sourceRect
有了sourceView和permittedArrowDirections還不能完全確定箭頭的位置新荤,還需要一個參數(shù),這個參數(shù)就是sourceRect台汇。上圖中設(shè)置的sourceRect為_button.bnounds苛骨,當(dāng)我們把sourceRect設(shè)置為CGRectMake(0, 0, _button.bounds.size.width, _button.bounds.size.height / 2.0);
也即是這個按鈕的上半?yún)^(qū)域的時候,我們看一下效果:
簡單應(yīng)用
TestViewController *testVC = [[TestViewController alloc] init];
testVC.preferredContentSize = CGSizeMake(150, 150);
testVC.modalPresentationStyle = UIModalPresentationPopover;
testVC.popoverPresentationController.delegate = self;
testVC.popoverPresentationController.sourceView = _button;
testVC.popoverPresentationController.sourceRect = CGRectMake(0, 0, _button.bounds.size.width / 2.0, _button.bounds.size.height / 2.0);
testVC.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionLeft;
testVC.popoverPresentationController.backgroundColor = [UIColor redColor];
testVC.popoverPresentationController.canOverlapSourceViewRect = NO;
[self presentViewController:testVC animated:YES completion:^{
}];
注意苟呐,這樣做的話是無論如何都不能成功顯示彈出視圖的痒芝,我們還需要實現(xiàn)代理的一個方法:
#pragma mark - <UIPopoverPresentationControllerDelegate>
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
這樣就能成功實現(xiàn)了。