=============UIPopPresentationController的使用、封装到分类中================
/**
UIpoppresentationViewController分类
使用:直接在要用的控制器中调用下面的方法即可
*/
#import <UIKit/UIKit.h>
#define POPFRAME CGRectMake(0, 0, 200, 300)
NS_ASSUME_NONNULL_BEGIN
static NSString * const popcellIdentfier=@"popcellIdentfier";
// 属性名称
static const char * key = "dataArrKey";//必须用char *,用NSString会报错
static const char * blockkey = "blockkey";//必须用char *,用NSString会报错
@interface UIViewController (LYBPopVC)<UIPopoverPresentationControllerDelegate,UITableViewDelegate,UITableViewDataSource>
/**
conditionBtn:popvc指向的view
dataArr:popvc上显示的数据
through:允许穿透的view数组(被popvc遮挡也能响应事件)
popFrame:popVC显示的大小
*/
-(UIViewController *)createPopVCWith:(UIButton *)conditionBtn datarArr:(NSArray *)dataArr throughArr:(NSArray *)throughArr popFrame:(CGRect)popFrame;
/**
下面的两个属性需要使用运行时动态添加
*/
@property(nonatomic,copy)void (^selectpopcellBlock)(NSString *str);
@property(nonatomic,strong)NSArray *dataArr;
@end
NS_ASSUME_NONNULL_END
#import "UIViewController+LYBPopVC.h"
#import <objc/message.h>
@implementation UIViewController (LYBPopVC)
//创建popvc,设置相应的属性 ,弹出povc
-(UIViewController *)createPopVCWith:(UIButton *)conditionBtn datarArr:(NSArray *)dataArr throughArr:(NSArray *)throughArr popFrame:(CGRect)popFrame{
self.dataArr=dataArr;
UIViewController *popvc=[[UIViewController alloc]init];
[self cgreatePopVCWithArr:dataArr povc:popvc popFrame:popFrame.size.width?popFrame:POPFRAME];//创建popvc
//设置popvc相关属性,弹出popvc
popvc.preferredContentSize=CGSizeMake(WIDTH/3, 300);//这个是要弹出来的控制器,在这个控制中设置pop出来的控制器显示大小 self.preferredContentSize=CGSizeMake(WIDTH/3, self.titleArr.count*44);///设置pop的大小
popvc.view.backgroundColor=[UIColor redColor];
//设置跳转模式为popover模式
popvc.modalPresentationStyle = UIModalPresentationPopover;
//获取到UIPopoverPresentationController对象
UIPopoverPresentationController* con = popvc.popoverPresentationController;
con.delegate=self;//设置代理
//设置弹出的基准视图
con.sourceView = conditionBtn;//以什么为基准
con.permittedArrowDirections= UIPopoverArrowDirectionUp;//箭头的方向
con.sourceRect=CGRectMake(20,20, 10,10);//设置尖头的位置
if(throughArr.count>0){
//. 设置穿透视图,设置哪些视图在popove显示的时候,仍旧能响应用户的点击事件
con.passthroughViews =throughArr;
}
[self presentViewController:popvc animated:YES completion:nil];//弹出pop视图
return self;
}
//调用了这个代理方法可以设置不全频幕显示
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller{
return UIModalPresentationNone;
}
-(void)cgreatePopVCWithArr:(NSArray *)datatArr povc:(UIViewController *)popvc popFrame:(CGRect)popFrame{
UITableView *tab=[[UITableView alloc]initWithFrame:popFrame style:UITableViewStylePlain];
tab.delegate=self;
tab.dataSource=self;
[popvc.view addSubview:tab];
tab.tableFooterView=[[UIView alloc]init];
[tab registerClass:[UITableViewCell class] forCellReuseIdentifier:popcellIdentfier];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataArr.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:popcellIdentfier];
cell.textLabel.text=self.dataArr[indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath];
cell.userInteractionEnabled=NO;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
cell.userInteractionEnabled=YES;
});
self.selectpopcellBlock(self.dataArr[indexPath.row]);
}
/**
动态添加属性dataArr
*/
// set方法
- (void)setDataArr:(NSString *)dataArr
{
// 让这个字符串与当前对象产生联系
/*
param1:object:给哪个对象添加属性
param2:key:属性名称
param3:value:属性值
param4:policy:保存策略
*/
objc_setAssociatedObject(self,key, dataArr, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
// get 方法
- (NSString *)dataArr
{
return objc_getAssociatedObject(self, key);
}
/**
动态添加属性selectpopcellBlock
*/
// set方法
-(void)setSelectpopcellBlock:(void (^)(NSString * _Nonnull))selectpopcellBlock{
// 让这个字符串与当前对象产生联系
/*
param1:object:给哪个对象添加属性
param2:key:属性名称
param3:value:属性值
param4:policy:保存策略
*/
objc_setAssociatedObject(self,blockkey, selectpopcellBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
// get 方法
-(void (^)(NSString * _Nonnull))selectpopcellBlock{
return objc_getAssociatedObject(self, blockkey);
}
@end
使用:
#import "UIViewController+LYBPopVC.h"
- (void)viewDidLoad {
[super viewDidLoad];
//这个按钮是popVC箭头的指向,按钮可以换成其他的view
UIButton *popBtn=[[UIButton alloc]initWithFrame:CGRectMake(100,100,100, 100)];
[popBtn setTitle:@"pop"forState:UIControlStateNormal];
popBtn.backgroundColor=[UIColor greenColor];
[self.view addSubview:popBtn];
[popBtn addTarget:self action:@selector(createPopVCWith:)forControlEvents:UIControlEventTouchDown];
}
-(void)createPopVCWith:(UIButton *)conditionBtn {
//一句话弹出popvc
[self createPopVCWith:conditionBtn datarArr:@[@"工商银行",@"建设银行",@"交通银行",@"招商银行",@"华夏银行",@"渤海银行",@"广发银行",@"平安银行",@"光大银行",@"民生银行",@"兴业银行",@"普通发展银行",@"邮政储蓄银行",@"农业银行",@"招商银行",@"招商银行"] throughArr:@[] popFrame:CGRectMake(0, 0, 0, 0)];
//选中popvc上的cell后的回调
self.selectpopcellBlock = ^(NSString * _Nonnull str) {
NSLog(@"-在这里执行相应的操作--%@",str);
};
}
/**
modalPresentationStyle:呈现样式
UIModalPresentationFullScreen 默认样式, 全屏
UIModalPresentationPageSheet 宽度保持768(横屏宽度),高跟View等高(会除去顶部状态栏)
UIModalPresentationFormSheet 居中显示, 占用屏幕的一部分 --> pad中较常见
*/
/**
modalTransitionStyle : 转场样式
UIModalTransitionStyleCoverVertical 垂直覆盖
UIModalTransitionStyleFlipHorizontal 类似win8的三维翻转效果
UIModalTransitionStyleCrossDissolve 淡入淡出
UIModalTransitionStylePartialCurl 翻页效果 --> 电子书类软件常见
注意事项:
遵循代理UIPopoverPresentationControllerDelegate
设置代理 popover.delegate=self;
注意:如果要去掉箭头 permittedArrowDirections = 0; 并且要在设置了 sourceView, sourceRect 之后才会生效
以前只能在iPad上面使用,先在iPhone页可以用,但是如果在iPhone上使用的话默认就会占满全屏幕,
解决办法是遵循UIPopoverPresentationControllerDelegate 实现adaptivePresentationStyleForPresentationController:代理方法覆盖默认的自适应行为
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
returnUIModalPresentationNone;
}
- // 是否可以dismiss,返回YES代表可以,返回NO代表不可以
- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {
return NO;
}
注意:preferredContentSize 应该在 presentedViewController(被弹出的控制器) 中实现,也可以重写preferredContentSize 的set get 方法来根据不同的新情况返回不同的尺寸
self.preferredContentSize=CGSizeMake(400, 200);
//重写这个poppresentAIonViewController才能改变大小
//- (CGSize)preferredContentSize {
//
// return CGSizeMake(200, 200);
//}
- (IBAction)buttonClick:(id)sender {
// iOS8以后的兼容写法
// iOS8的时候,系统将popove作为模态视图的一种呈现样式
// 当系统检测到设备是iPhone时,直接以普通视图弹出
// 当系统检测到设备是iPad时,会以popover弹出
//1. 创建内容控制器
ImitateNavBarTileViewVC *tileVC=[[ImitateNavBarTileViewVCalloc]init];
//2. 设置模态视图的呈现样式
tileVC.modalPresentationStyle =UIModalPresentationPopover;
//3. 设置UIPopoverPresentationController
// UIPopoverPresentationController *popover=[[UIPopoverPresentationController alloc]initWithPresentedViewController:<#(nonnull UIViewController *)#> presentingViewController:<#(nullable UIViewController *)#>];
//从iOS8以后, UIViewController,新增了一个属性popoverPresentationController
UIPopoverPresentationController *popover = tileVC.popoverPresentationController;
//3.1 指向BarButtonItem按钮
// popover.barButtonItem = self.navigationItem.leftBarButtonItem;
// popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
//3.2 指向自定义视图 -->箭头方向可以不设置,默认就是Any
popover.delegate=self;
popover.sourceView =self.titleView;
popover.sourceRect =self.titleView.bounds;
popover.permittedArrowDirections=UIPopoverArrowDirectionUp;
//4. 模态视图弹出
[selfpresentViewController:tableVCanimated:YEScompletion:nil];
}
- (void)popoveriOS8
{
// iOS8以前的兼容写法 -->判断设备的类型
//1. 创建内容控制器
TableViewController *tableVC = [TableViewControllernew];
if ([UIDevicecurrentDevice].userInterfaceIdiom ==UIUserInterfaceIdiomPad ) {
//2. 创建popover
UIPopoverController *popover = [[UIPopoverControlleralloc]initWithContentViewController:tableVC];
//3. 弹出popover
[popover presentPopoverFromBarButtonItem:self.navigationItem.leftBarButtonItempermittedArrowDirections:UIPopoverArrowDirectionAnyanimated:YES];
} elseif ([UIDevicecurrentDevice].userInterfaceIdiom ==UIUserInterfaceIdiomPhone) {
// 如果是iPhone, 则使用模态视图弹出即可
[selfpresentViewController:tableVCanimated:YEScompletion:nil];
}
}
===========================================
#import "ViewController.h"
#import "TableViewController.h"
@interface ViewController ()<UIPopoverControllerDelegate>
@property (weak, nonatomic) IBOutletUIButton *redButton;
@property (weak, nonatomic) IBOutletUIButton *blueButton;
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
//带有箭头指向的弹窗视图,显示在界面的最前面
- (IBAction)categoryClick:(id)sender {
//1. 创建内容控制器
TableViewController *tableVC = [TableViewControllernew];
//2. 创建Popover
UIPopoverController *popover = [[UIPopoverControlleralloc]initWithContentViewController:tableVC];
//3. 显示popover
[popover presentPopoverFromBarButtonItem:self.navigationItem.leftBarButtonItempermittedArrowDirections:UIPopoverArrowDirectionAnyanimated:YES];
//4. 设置大小 默认大小是320 * 480
//两种方式:
// 一. 当前控制器中: popoverContentSize -->不推荐使用
// 二. 内容控制器中:preferredContentSize -->应该使用此属性来设置
popover.popoverContentSize = CGSizeMake(320, 3 * 44);
}
- (IBAction)redViewClick:(id)sender {
//1. 创建内容控制器
TableViewController *tableVC = [TableViewControllernew];
UINavigationController *nav = [[UINavigationControlleralloc]initWithRootViewController:tableVC];
//2. 创建Popover
UIPopoverController *popover = [[UIPopoverControlleralloc]initWithContentViewController:nav];
//3. 显示popover
//inView : 要指向的视图]
//Rect : 以指向的视图左上角为(0, 0)点,然后根据rect参数来定位
//ArrowDirection: 箭头方向, 一般都传Any,避免界面发生遮挡现象
[popover presentPopoverFromRect:self.redButton.boundsinView:self.redButtonpermittedArrowDirections:UIPopoverArrowDirectionAnyanimated:YES];
//[popover presentPopoverFromRect:self.redButton.frame inView:self.redButton.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
//4. 处理block
tableVC.selectColorBlock = ^(UIColor *color) {
//4.1 更改颜色 --> 传值
self.redButton.backgroundColor = color;
//4.2 消失popover
//[popover dismissPopoverAnimated:YES];
//5. 更改pooove的大小 -->带动画
//popover.popoverContentSize = CGSizeMake(100, 800);
// 不带动画, 可以用方法来实现 -->一般不推荐
//[popover setPopoverContentSize:CGSizeMake(100, 800) animated:NO];
//6. 更改内容控制器 --> 属性默认不带动画
UIViewController *vc = [UIViewControllernew];
vc.view.backgroundColor = [UIColorblueColor];
popover.contentViewController = vc;
// 带动画, 可以用方法来实现
//[popover setContentViewController:vc animated:YES];
};
//7. 设置穿透视图,设置哪些视图在popove显示的时候,仍旧能响应用户的点击事件
popover.passthroughViews = @[self.blueButton];
//8. 代理
popover.delegate = self;
}
- (IBAction)blueViewClick:(id)sender {
NSLog(@"点我啊");
}
#pragma mark 代理方法
// 设置点击背景时, 能否消失popover . 默认就是yes
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
return YES;
}
// 完成popove消失时调用 -->可以将一些需要保存的操作,放到这里
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
NSLog(@"%s",__func__);
}
// 当屏幕旋转的时候会调用
- (void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inoutCGRect *)rect inView:(inoutUIView *__autoreleasing _Nonnull *)view
{
NSLog(@"%s",__func__);
}
}
=========================
pop视图中视图压缩的问题:
// 如果AotoLayout勾选了,那么autoresizingMask默认会有跟上面及左边的联系.
// 所以,当视图发生大小的改变时,就会发生相对应的压缩行为.
//popover默认大小320 * 480 iPad控制器1024 *768
//当大的控制器,放大较小的控制器中中,就会发生压缩
//autoresizingMask : 自动伸缩
self.autoresizingMask =UIViewAutoresizingNone;
======================
iOS9中UIPoppresentationController代替UIPopoverController;
#import <UIKit/UIKit.h>
@class PopVC;
@protocol PopVCDelegate<NSObject>
-(void)PopVC:(PopVC *)PopVC bankname:(NSString *)bankname;
@end
@interface PopVC :UIViewController
@property(nonatomic,assign)id<PopVCDelegate>delegate;
@end
*********
#import "PopVC.h"
#import "Header.h"
@interface PopVC ()<UITableViewDelegate,UITableViewDataSource>
@property(nonatomic,strong)UITableView *tab;
@property(nonatomic,strong)NSArray *creditArr;//银行列表
@end
static NSString *const identifier=@"wlbcreditcell";
@implementation PopVC
-(NSArray *)creditArr{
if(nil==_creditArr){
_creditArr=@[@"工商银行",@"建设银行",@"交通银行",@"招商银行",@"华夏银行",@"渤海银行",@"",@"广发银行",@"平安银行",@"光大银行",@"民生银行",@"兴业银行",@"普通发展银行",@"邮政储蓄银行",@"农业银行",@"招商银行",@"招商银行"];
}
return_creditArr;
}
- (void)viewDidLoad {
[superviewDidLoad];
self.preferredContentSize=CGSizeMake(WIDTH/2,HEIGHT-100);//pop显示大小
[selfsetTable];
}
-(void)setTable{
UITableView *tab=[[UITableViewalloc]initWithFrame:CGRectMake(0,0,WIDTH,HEIGHT-64)style:UITableViewStylePlain];
if(HEIGHT==812){
tab=[[UITableViewalloc]initWithFrame:CGRectMake(0,0,WIDTH,HEIGHT-34-88)style:UITableViewStylePlain];
}
tab.showsVerticalScrollIndicator=NO;
tab.delegate=self;
tab.dataSource=self;
self.tab=tab;
[self.viewaddSubview:tab];
// tab.backgroundColor=[UIColor colorWithHexString:@"#f6f6f6" alpha:1];
tab.tableFooterView=[[UIViewalloc]init];
tab.separatorStyle=UITableViewCellSelectionStyleNone;
[tab registerClass:[UITableViewCellclass]forCellReuseIdentifier:identifier];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.creditArr.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell=[tableViewdequeueReusableCellWithIdentifier:identifier];
if(self.creditArr.count>0){
cell.textLabel.text=self.creditArr[indexPath.row];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//防连续点击
UITableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath];
cell.userInteractionEnabled=NO;
NSLog(@"cellNO");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
cell.userInteractionEnabled=YES;
NSLog(@"cellYES");
});
[tableView deselectRowAtIndexPath:indexPathanimated:YES];
if(self.creditArr.count>0){
if([self.delegaterespondsToSelector:@selector(PopVC:bankname:)]){
[self.delegatePopVC:selfbankname:self.creditArr[indexPath.row]];
}
}
}
@end
***************
#import <UIKit/UIKit.h>
@interface LYPopPresentationController : UIViewController
@end
*************
#import "LYPopPresentationController.h"
#import "PopVC.h"
@interface LYPopPresentationController ()<UIPopoverPresentationControllerDelegate,PopVCDelegate>
@property(nonatomic,strong)UIButton *popBtn;
@property(nonatomic,strong)PopVC *popVC;
@property(nonatomic,strong)UITextField *bankNameTF;//开户行
@end
@implementation LYPopPresentationController
- (void)viewDidLoad {
[superviewDidLoad];
UIButton *popBtn=[[UIButtonalloc]initWithFrame:CGRectMake(100,100,100, 100)];
[popBtn setTitle:@"pop"forState:UIControlStateNormal];
popBtn.backgroundColor=[UIColorgreenColor];
[self.viewaddSubview:popBtn];
[popBtn addTarget:selfaction:@selector(pop:)forControlEvents:UIControlEventTouchDown];
}
-(void)pop:(UIButton *)btn{
[selfpopToBankList];
}
//开户行
-(void)popToBankList{
PopVC *popvc=[[PopVCalloc]init];
self.popVC=popvc;
//设置跳转模式为popover模式
popvc.modalPresentationStyle =UIModalPresentationPopover;
//获取到UIPopoverPresentationController对象
UIPopoverPresentationController* con = popvc.popoverPresentationController;
con.delegate=self;//设置代理
//设置弹出的基准视图
con.sourceView = self.bankNameTF;//以什么为基准
con.permittedArrowDirections= UIPopoverArrowDirectionLeft;//箭头的方向
con.sourceRect=CGRectMake(50,20,10,10);//设置尖头的位置
//. 设置穿透视图,设置哪些视图在popove显示的时候,仍旧能响应用户的点击事件
con.passthroughViews =@[self.bankNameTF];
// 代理
popvc.delegate = self;
con.delegate=self;
[selfpresentViewController:popvcanimated:YEScompletion:nil];//弹出pop视图
}
-(void)PopVC:(PopVC *)PopVC bankname:(NSString *)bankname{
self.bankNameTF.text=bankname;
[self.popVCdismissViewControllerAnimated:YEScompletion:nil];//消失pop
}
//调用了这个代理方法可以设置不全频幕显示
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller{
returnUIModalPresentationNone;
}
@end