iOS开发基础知识--碎片20
1:view中的clipsTobounds属性
iew2添加view1到中,如果view2大于view1,或者view2的坐标不全在view1的范围内,view2是盖着view1的,意思就是超出的部份也会画出来,UIView有一个属性,clipsTobounds 默认情况下是NO。如果,我们想要view2把超出的那部份隐藏起来的话,就得改变它的父视图也就view1的clipsTobounds属性值。view1.clipsTobounds = YES; 可以很好地解决覆盖的问题
2:UIScrollView滚动视图加载单元格点击事件
svView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, mainWidth, perHeight)]; svView.bounces = NO; svView.contentSize = CGSizeMake(perWidth*6, perHeight); UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClick:)]; [self addGestureRecognizer:tap]; [self addSubview:svView]; 事件: - (void)tapClick:(UITapGestureRecognizer*)tap { CGPoint point = [tap locationInView:svView]; int page = point.x / perWidth; HomeHostest* hot = [myData objectAtIndex:page]; if(delegate) { [delegate adClick:[NSString stringWithFormat:@"goodsdetail,%@",[hot.goodsID stringValue]]]; } } - (CGPoint)locationInView:(UIView *)view:函数返回一个CGPoint类型的值,表示触摸在view这个视图上的位置,这里返回的位置是针对view的坐标系的。调用时传入的view参数为空的话,返回的时触摸点在整个窗口的位置。 (CGPoint)previousLocationInView:(UIView *)view:该方法记录了前一个坐标值,函数返回也是一个CGPoint类型的值, 表示触摸在view这个视图上的位置,这里返回的位置是针对view的坐标系的。调用时传入的view参数为空的话,返回的时触摸点在整个窗口的位置。
3:对表格中的某个节跟每一行进行单独刷新
[self.myTableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
4:类似微信的搜索附近的人的功能 在 服务端的实现
基准线预先计算法 每个用户在服务器端都会保留最后的经度j1 和纬度w1 的同时 保留对经度基准线的相对距离 dj1 和纬度基准线的相对距离 dw1 经度基准线可以是中国最东边的经度 纬度基准线可以是中国最北边的纬度 当前用户对经度基准线的相对距离 dj2 =230km 和纬度基准线的相对距离 dw2=350km 查找时sql语句可以这么写(1.5公里内的用户) select * from user where dj1>(230-1.5) and dj1<(230+1.5) and dw1>(230-1.5) and dw1<(230+1.5) 相当于获得当前用户 周围正方形1.5公里区域的用户 此外通过将冷热数据分开存放及 分块存放 用户地理数据应该能有效的提高查询速度 另附:(考虑把经度和纬度分成多个表存放,比如24个经度表,每个表按纬度分别排序,查找时只在最靠近的那个表查找,由于是排序的所以并不需要遍历每个记录,比如纬度相差多少的就不用再找了。 )
5:定位一些基础内容 CLLocation
01. CLLocation -------------------------------------------------------- CLLocationManager 定位管理者 CLLocation 代表位置(经度/纬度/高度/速度/路线等) CLHeading 代表移动方向 CLRegion 代表一个区域 >CLCircularRegion 圆形区域 >CLBeaconRegion 蓝牙信号区域 返回定位服务是否可用 [CLLocationManager locationServicesEnabled]; 返回延迟定位更新是否可用 [CLLocationManager deferredLocationUpdatesAvailable]; 返回重大位置改变监听是否可用 [CLLocationManager significantLocationChangeMonitoringAvailable]; 返回是否支持磁力计算方向 [CLLocationManager headingAvailable]; 返回蓝牙信号范围服务是否可用 [CLLocationManager isRangingAvailable]; -------------------------------------------------------- 设置是否可以暂停定位来节省电池电量, YES不需要定位数据时自动暂停定位 // mgr.pausesLocationUpdatesAutomatically -------------------------------------------------------- 每隔多少米定位一次, 只有水平方向超过该值时才会重新定位 // mgr.distanceFilter = 100; -------------------------------------------------------- 定位精确度 // mgr.desiredAccuracy; kCLDistanceFilterNone; kCLLocationAccuracyBestForNavigation 导航级最佳精准 kCLLocationAccuracyBest; 最佳精准 kCLLocationAccuracyNearestTenMeters; 10米误差 kCLLocationAccuracyHundredMeters; 百米胡茬 kCLLocationAccuracyKilometer; 千米误差 kCLLocationAccuracyThreeKilometers; 3千米误差 -------------------------------------------------------- 定位数据的用途 // mgr.activityType; CLActivityTypeOther 作为普通用途 CLActivityTypeAutomotiveNavigation 作为车辆导航 CLActivityTypeFitness 作为步行 CLActivityTypeOtherNavigation 作为其它导航 -------------------------------------------------------- // CLLocation location.coordinate; 坐标, 包含经纬度 location.altitude; 设备海拔高度 单位是米 location.course; 设置前进方向 0表示北 90东 180南 270西 location.horizontalAccuracy; 水平精准度 location.verticalAccuracy; 垂直精准度 location.timestamp; 定位信息返回的时间 location.speed; 设备移动速度 单位是米/秒, 适用于行车速度而不太适用于步行 /* 可以设置模拟器模拟速度 bicycle ride 骑车移动 run 跑动 freeway drive 高速公路驾车 */ -------------------------------------------------------- // CLAuthorizationStatus 用户从未选择过权限 kCLAuthorizationStatusNotDetermined 无法使用定位服务,该状态用户无法改变 kCLAuthorizationStatusRestricted 用户拒绝该应用使用定位服务,或是定位服务总开关处于关闭状态 kCLAuthorizationStatusDenied 已经授权(废弃) kCLAuthorizationStatusAuthorized 用户允许该程序无论何时都可以使用地理信息 kCLAuthorizationStatusAuthorizedAlways 用户同意程序在可见时使用地理位置 kCLAuthorizationStatusAuthorizedWhenInUse -------------------------------------------------------- // 计算两个位置之间的距离, 单位是米 [newLocation distanceFromLocation:self.prevLocation]; -------------------------------------------------------- 获取方向信息不会提示用户(不需要授权), 因为不会泄露隐私 // [self.mgr startUpdatingHeading]; magneticHeading 设备与磁北的相对角度 trueHeading 设置与真北的相对角度, 必须和定位一起使用, iOS需要设置的位置来计算真北 真北始终指向地理北极点 磁北对应随着时间变化的地球磁场北极 // 牛逼的地方 116.958776,36.721199 -------------------------------------------------------- // 错误:使用CoreLocation获取地理位置信息,报错 Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error 0.)" 解决方法: 1.确定模拟器(手机)已经联网并且允许程序获取地理位置 2.重置地理位置服务或者网络服务 PS:如果是模拟器就果断直接重置模拟器吧 IOS Simulator - Reset Content and Settings..。 /* 注意: iOS7只要开始定位, 系统就会自动要求用户对你的应用程序授权. 但是从iOS8开始, 想要定位必须先"自己""主动"要求用户授权 在iOS8中不仅仅要主动请求授权, 而且必须再info.plist文件中配置一项属性才能弹出授权窗口 NSLocationWhenInUseDescription,允许在前台获取GPS的描述 NSLocationAlwaysUsageDescription,允许在后台获取GPS的描述 */
6:CGPoint一些常见操作
数据结构中的一个点CGPoint代表在一个二维坐标系统。数据结构的位置和尺寸CGRect代表的一个长方形。数据结构的尺寸CGSize代表宽度和高度。 1、创建一个几何原始数值 CGPoint CGPointMake(CGPoint A,CGPoint B) 返回一个指定坐标点 CGRect CGRectMake(CGFloat x,CGFloat y,CGFloat width,CGFloat height) 根据指定的坐标和大小创建一个矩形 CGSize CGSizeMake(CGFloat width,CGFloat height) 根据指定长宽创建一个CGSize 2、修改矩形 CGRectDivide CGRect CGRectInset(CGRect rect,CGFloat dx,CGFloat dy) 返回一个比原矩形大或小的矩形,但是中心点是相同的 CGRect CGRectIntegral(CGRect A) 将矩形A的值转变成整数,得到一个最小的矩形, CGRect CGRectIntersection:(CGRect A,CGRect B) 获取两个矩形相交处所的矩形,没有相交返回NULL,用CGRectIsNull来检测 CGRectOffset CGRectStandardize CGRectUnion 3、比较数值 bool CGPointEqualToPoint(CGPoint A,CGPoint B) 返回两个点是否相等 bool CGSizeEqualToSize(CGSize A,CGSize B) CGSizeAB是否相等 bool CGRectEqualToRect(CGRect A,CGRect B) 矩形AB的位置大小是否相等 bool CGRectIntersectsRect(CGRect A,CGRect B) 矩形AB是否相交,可用来判断精灵是否离开了屏幕 4、检查 bool CGRectContainsPoint(CGRect A, CGPoint B) 检测矩形A是否包含指定的点B bool CGRectContainsRect(CGRect A,CGRect B) 检测矩形A是否包含矩形B 5、获取最大值、中等职和最小值 CGFloat CGRectGetMinX(CGRect A) 获取矩形x坐标的最小值 CGFloat CGRectGetMinY(CGRect A) 获取矩形y坐标的最小值 CGFloat CGRectGetMidX(CGRect A) 获取矩形x坐标的中间值 CGFloat CGRectGetMidY(CGRect A) 获取矩形y坐标的中间值 CGFloat CGRectGetMaxX(CGRect A) 获取矩形x坐标的最大值 CGFloat CGRectGetMaxY(CGRect A) 获取矩形y坐标的最大值 6、获取高和宽 CGFloat CGRectGetHeight(CGRect A) 获取矩形A的高 CGFloat CGRectGetWidth(CGRect A) 获取矩形A的宽 7、检测矩形是否存在或是无穷大 bool CGRectIsEmpty(CGRect A) 矩形A是否长和宽都是0,或者是个NULL bool CGRectIsNull(CGRect A) 矩形A是否为NULL bool CGRectIsInfinite(CGRect A) 矩形A是否无穷大,没有边界
7:iOS7 中 boundingRectWithSize:options:attributes:context:计算文本尺寸的使用
之前使用了NSString类的sizeWithFont:constrainedToSize:lineBreakMode:方法,但是该方法已经被iOS7 Deprecated了,而iOS7新出了一个boudingRectWithSize:options:attributes:context方法来代替。 而具体怎么使用呢,尤其那个attribute NSDictionary *attribute = @{NSFontAttributeName: [UIFont systemFontOfSize:13]}; CGSize size = [@“相关NSString” boundingRectWithSize:CGSizeMake(100, 0) options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attribute context:nil].size; 属性 a:NSStringDrawingTruncatesLastVisibleLine: 如果文本内容超出指定的矩形限制,文本将被截去并在最后一个字符后加上省略号。如果没有指定NSStringDrawingUsesLineFragmentOrigin选项,则该选项被忽略。 b:NSStringDrawingUsesLineFragmentOrigin: 绘制文本时使用 line fragement origin 而不是 baseline origin。 c:NSStringDrawingUsesFontLeading: 计算行高时使用行距。(译者注:字体大小+行间距=行距) d:NSStringDrawingUsesDeviceMetrics: 计算布局时使用图元字形(而不是印刷字体)。 实例二: NSString *str = @"正在搜索附近的位置"; UIFont *font = [UIFont systemFontOfSize:14.0]; CGSize size = CGSizeMake(CGFLOAT_MAX, 50); CGRect rect = [str boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont fontWithName:font.fontName size:font.pointSize]} context:nil]; CGRect buttonFrame = CGRectZero; buttonFrame.size.height = CGRectGetHeight(rect); buttonFrame.size.width = CGRectGetWidth(rect); UILabel *label = [[UILabel alloc]initWithFrame:buttonFrame];
8:一段布局排版关于tableView.tableFooterView设置按键跟等待提示
- (UIView *)searchDisplayLoadingFooterView { if (!_searchDisplayLoadingFooterView) { _searchDisplayLoadingFooterView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.tableView.bounds), 50)]; _searchDisplayLoadingFooterView.backgroundColor = [UIColor clearColor]; NSString *str = @"正在搜索附近的位置"; UIFont *font = [UIFont systemFontOfSize:14.0]; CGSize size = CGSizeMake(CGFLOAT_MAX, 50); CGRect rect = [str boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont fontWithName:font.fontName size:font.pointSize]} context:nil]; CGRect buttonFrame = CGRectZero; buttonFrame.size.height = CGRectGetHeight(rect); buttonFrame.size.width = CGRectGetWidth(rect); UILabel *label = [[UILabel alloc]initWithFrame:buttonFrame]; label.backgroundColor = [UIColor clearColor]; label.text = str; label.font = font; label.textColor = [UIColor colorWithHexString:@"0x222222"]; label.numberOfLines = 1; label.textAlignment = NSTextAlignmentCenter; label.center = _searchDisplayLoadingFooterView.center; [_searchDisplayLoadingFooterView addSubview:label]; CGPoint indicatorCenter = CGPointZero; indicatorCenter.x = CGRectGetMinX(label.frame) - 20; indicatorCenter.y = label.center.y; UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; indicator.center = indicatorCenter; indicator.hidesWhenStopped = YES; [_searchDisplayLoadingFooterView addSubview:indicator]; [indicator startAnimating]; CGRect lineFrame = _searchDisplayLoadingFooterView.bounds; lineFrame.size.height = 0.5; UIView *topLine = [[UIView alloc]initWithFrame:lineFrame]; topLine.backgroundColor = [UIColor colorWithHexString:@"0xdddddd"]; lineFrame.origin.y = CGRectGetMaxY(_searchDisplayLoadingFooterView.bounds) - 0.5; UIView *bottomLine = [[UIView alloc]initWithFrame:lineFrame]; bottomLine.backgroundColor = [UIColor colorWithHexString:@"0xdddddd"]; [_searchDisplayLoadingFooterView addSubview:topLine]; [_searchDisplayLoadingFooterView addSubview:bottomLine]; } return _searchDisplayLoadingFooterView; }
9:百度坐标跟火星坐标相互转换
//百度转火星坐标 + (CLLocationCoordinate2D )bdToGGEncrypt:(CLLocationCoordinate2D)coord { double x = coord.longitude - 0.0065, y = coord.latitude - 0.006; double z = sqrt(x * x + y * y) - 0.00002 * sin(y * M_PI); double theta = atan2(y, x) - 0.000003 * cos(x * M_PI); CLLocationCoordinate2D transformLocation ; transformLocation.longitude = z * cos(theta); transformLocation.latitude = z * sin(theta); return transformLocation; } //火星坐标转百度坐标 + (CLLocationCoordinate2D )ggToBDEncrypt:(CLLocationCoordinate2D)coord { double x = coord.longitude, y = coord.latitude; double z = sqrt(x * x + y * y) + 0.00002 * sin(y * M_PI); double theta = atan2(y, x) + 0.000003 * cos(x * M_PI); CLLocationCoordinate2D transformLocation ; transformLocation.longitude = z * cos(theta) + 0.0065; transformLocation.latitude = z * sin(theta) + 0.006; return transformLocation; }