本文共 16329 字,大约阅读时间需要 54 分钟。
=============UIPopPresentationController的使用、封装到分类中================
/** UIpoppresentationViewController分类 使用:直接在要用的控制器中调用下面的方法即可 */#import#define POPFRAME CGRectMake(0, 0, 200, 300)NS_ASSUME_NONNULL_BEGINstatic NSString * const popcellIdentfier=@"popcellIdentfier";// 属性名称static const char * key = "dataArrKey";//必须用char *,用NSString会报错static const char * blockkey = "blockkey";//必须用char *,用NSString会报错@interface UIViewController (LYBPopVC) /** 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;@endNS_ASSUME_NONNULL_END#import "UIViewController+LYBPopVC.h"#import @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;
}
注意: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
转载地址:http://hhlgi.baihongyu.com/