首页 > 代码库 > iOS_21团购_Popover适应iPad横竖屏切换

iOS_21团购_Popover适应iPad横竖屏切换

最终效果图:



代码片段:

//
//  DockItemLocation.m
//  帅哥_团购
//
//  Created by beyond on 14-8-13.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//

#import "DockItemLocation.h"
// 点击dock上面的locationBtn,弹出的Popover封装的控制器,其上方是搜索栏,下方是tableView
#import "CityLocationController.h"

// 按钮上面是图片,下面是文字,这是图片在高度上的比例
#define kImageHeightRatioInBtn 0.5


@interface DockItemLocation()<UIPopoverControllerDelegate>
{
    //popover控制器,创建出来之后,show方法显示,因此不可以是局部变量,必须用成员变量记住,否则方法btnClick调用完毕就销毁了,还如何 显示捏?
    UIPopoverController *_popoverCtrl;
}
@end
@implementation DockItemLocation

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // 1.调用父类的方法,设置内部的图片
        [self setIcon:@"ic_district.png" selectedIcon:@"ic_district_hl.png"];
        
        // 2.自动伸缩
        self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
        
        // 3.设置默认的文字
        [self setTitle:@"定位中" forState:UIControlStateNormal];
        self.titleLabel.font = [UIFont systemFontOfSize:16];
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
        [self setTitleColor:[UIColor whiteColor] forState:UIControlStateDisabled];
        [self setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        
        // 4.设置图片属性
        self.imageView.contentMode = UIViewContentModeCenter;
        
        // 5.监听点击【Location定位】,弹出一个Popover控制器
        [self addTarget:self action:@selector(locationBtnOnDockClicked) forControlEvents:UIControlEventTouchDown];
    }
    return self;
}
// 5.监听点击【Location定位】,弹出一个Popover控制器
- (void)locationBtnOnDockClicked
{
    // 禁用,只可点击一次
    self.enabled = NO;
    // 点击dock上面的locationBtn,弹出的Popover封装的控制器,其上方是搜索栏,下方是tableView
    CityLocationController *cityVC = [[CityLocationController alloc] init];
    
    // 唯一一个不是继承自UIViewController的控制器,它继承自NSObject
    //popover控制器,创建出来之后,show方法显示,因此不可以是局部变量,必须用成员变量记住,否则方法btnClick调用完毕就销毁了,还如何 显示捏?
    _popoverCtrl = [[UIPopoverController alloc] initWithContentViewController:cityVC];
    // 设置这个Popover控制器的显示的大小
    _popoverCtrl.popoverContentSize = CGSizeMake(320, 480);
    // 代理,监听Popover控制器的XX事件
    _popoverCtrl.delegate = self;
    // 因为其他方法也要显示,_popoverCtrl,所以抽取成自定义方法
    [self showPopoverCtrl];
    
    // 因为屏幕旋转时,弹出的popover的指向的位置就不对了,所以有必要注册监听屏幕旋转的通知
    // 先移除监听器,保证健壮性
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
    // 再添加一个监听器,一旦设备出现UIDeviceOrientationDidChangeNotification,就会调用observer的selector方法
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(screenDidRotated) name:UIDeviceOrientationDidChangeNotification object:nil];
}
// 5-1,因为侦听到屏幕旋转了,也要再次显示_popoverCtrl,所以抽取成自定义方法
- (void)showPopoverCtrl
{
    // 显示到哪里? 如果目标view是self自己,则rect使用bounds,因为bounds的原点才是相对于自己
    // 如果目标view是self.superView,则rect使用frame,因为frame的原点才是相对于父控件
    [_popoverCtrl presentPopoverFromRect:self.bounds inView:self permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
// 5-2,再添加一个监听器,一旦设备出现UIDeviceOrientationDidChangeNotification,就会调用observer的selector方法
- (void)screenDidRotated
{
    if (_popoverCtrl.popoverVisible) {
        // 1.    关闭之前位置上面的_popoverCtrl
        [_popoverCtrl dismissPopoverAnimated:NO];
        
        // 2.    0.5秒后创建新的位置上的_popoverCtrl
        [self performSelector:@selector(showPopoverCtrl) withObject:nil afterDelay:0.5];
    }
}
#pragma mark - popOver代理方法
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
    // 消失前,让定位按钮恢复可以点击状态
    self.enabled = YES;
    
    // 消失前,即popover被销毁的时候,移除注册的监听器(通知)
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}


#pragma mark - 销毁时,移除当前对控制器对屏幕的监听,防止野指针
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}


#pragma mark - 覆写调整图片和文字在按钮中的Frame
- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
    CGFloat btnW = contentRect.size.width;
    CGFloat imgH = contentRect.size.height * kImageHeightRatioInBtn;
    return CGRectMake(0, 0, btnW, imgH);
}

- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
    CGFloat btnW = contentRect.size.width;
    CGFloat textH = contentRect.size.height * (1 - kImageHeightRatioInBtn);
    // 文字在下面,图片在上面
    CGFloat textY = contentRect.size.height - textH;
    return CGRectMake(0, textY, btnW, textH);
}

@end