前面在说mapkit程序里使用google geocoding api时,有这样的一个问题,因为google按地点名进行查询是模糊匹配的,
这样就会有返回很多个结果的情况,这时我们在程序中就要做相应的处理,以确定用户到底需要的是哪一个地点的信息。
一个友好的方式是弹出一个alert,alert中有全部匹配的地点项,用户可以选择一个做为自己需要的,然后程序在通过mapview
显示出相应地点的信息出来。
于是这样一个在UIAlertView中加入UITableView的想法就产生了,开始自己想得很简单,
因为uiAlertView也有addsubview的方法,于是认为新建一个UITableView,然后加入alertview里就好了。
于是直接用代码写了一个加入的方法,datasource和delegate都没去管,先试一下嘛。
程序运行,结果发现tableview是加入成功了,但是根本不按初始化时的frame来布局,tableview挡在了alertview的上面,
要多难看有多难看。
不过既然能加进去,布局的问题应该有办法解决才对,无奈人品不好,找了半天也没找到合适的方法解决。
只能换一种思路来做了。
创建一个UIAlertView的子类,然后子类中有自己的UITableView,这样会不会好一点呢?
不过布局仍然是一个问题,不过东西都在自己的类里面,在alertview显示的时候把布局重新设置一下,
这样应该可以解决问题,查到一个叫drawRect的方法,但好像仍然没法达到效果。
不过又找到一很好的文章:http://codesofa.com/blog/archive/2009/07/15/look-uialertview-is-dating-uitableview.html
它里面是reload UIAlertView的一个叫做ayoutAnimated:(BOOL)animated的私有api来达到布局的效果,
在把tableview插入到alertview之后,调用alertview的setNeedsLayout方法,就可以用上面的那个私有api来进行布局。
具体的代码如下:
UIAlertTableView.h
#import <UIKit/UIKit.h>@class UIAlertView;@interface UIAlertTableView : UIAlertView { // The Alert View to decorate UIAlertView *alertView; // The Table View to display UITableView *tableView; // Height of the table int tableHeight; // Space the Table requires (incl. padding) int tableExtHeight; id<UITableViewDataSource> dataSource; id<UITableViewDelegate> tableDelegate;}@property (nonatomic, assign) id dataSource;@property (nonatomic, assign) id tableDelegate;@property (nonatomic, readonly) UITableView *tableView;@property (nonatomic, assign) int tableHeight;- (void)prepare;@end
UIAlertTableView.m
#import "UIAlertTableView.h"#define kTablePadding 8.0f@interface UIAlertView (private)- (void)layoutAnimated:(BOOL)fp8;@end@implementation UIAlertTableView@synthesize dataSource;@synthesize tableDelegate;@synthesize tableHeight;@synthesize tableView;- (void)layoutAnimated:(BOOL)fp8 { [super layoutAnimated:fp8]; [self setFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y - tableExtHeight/2, self.frame.size.width, self.frame.size.height + tableExtHeight)]; // We get the lowest non-control view (i.e. Labels) so we can place the table view just below UIView *lowestView; int i = 0; while (![[self.subviews objectAtIndex:i] isKindOfClass:[UIControl class]]) { lowestView = [self.subviews objectAtIndex:i]; i++; } CGFloat tableWidth = 262.0f; tableView.frame = CGRectMake(11.0f, lowestView.frame.origin.y + lowestView.frame.size.height + 2 * kTablePadding, tableWidth, tableHeight); for (UIView *sv in self.subviews) { // Move all Controls down if ([sv isKindOfClass:[UIControl class]]) { sv.frame = CGRectMake(sv.frame.origin.x, sv.frame.origin.y + tableExtHeight, sv.frame.size.width, sv.frame.size.height); } } }//rewrite the show method of UIAlertView- (void)show{ [self prepare]; [super show];}- (void)prepare { if (tableHeight == 0) { tableHeight = 150.0f; } tableExtHeight = tableHeight + 2 * kTablePadding; tableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 0.0f, 0.0f) style:UITableViewStylePlain]; tableView.delegate = tableDelegate; tableView.dataSource = dataSource; [self insertSubview:tableView atIndex:0]; [self setNeedsLayout];}- (void)dealloc { [tableView release]; [super dealloc];}@end
这样布局的问题就解决了,一个定制的uialertview就完成了,
使用的时候,用如下代码进行一下配置:
UIAlertTableView *alert = [[UIAlertTableView alloc] initWithTitle:@"Select Option" message:@"select option or create one" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Create", nil];alert.tableDelegate = self;alert.dataSource = self;alert.tableHeight = 120;
当然,在要使用这个uialerttableview的文件里,要实现UITableViewDelegate,UITableViewDataSource这两个协议,
否则,tablview里就是空的喽,tableview的设置都可以在此文件中做配置,用赶来还是很方便的。
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #7340a3}span.s1 {color: #000000}
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #3f217c}