最終效果圖:
代碼片段:<喎?/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjwvcD4KPHA+PHByZSBjbGFzcz0="brush:java;">//
// 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()
{
//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