iOS UIPopoverController以及iOS9以后UIPopPresentationController的使用、封装到分类中

=============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.permittedArrowDirectionsUIPopoverArrowDirectionLeft;//箭头的方向

    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

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值