ios 设置view隐藏结果还是显示 ios版是什么意思原因

UITableViewCell的highlighted&和selected&属性
将UITableViewCell的selectedBackgroundView设置为按下图片的状态,同时不支持多选的情况下,遇到如下问题:
如果默认第一个cell处于selected状态,然后再点击其他的cell并不抬起(可以是长按操作),然后关闭当前的TableView,在通过其他操作之显示(每次显示的的时候,都会默认第一cell选中),就会出现之前长按的cell还是处于选中状态,此时虽然UITableView不支持多行选择,不甚明了,查阅资料发现:
具体参考:&http://www.itniwo.net/blog/v/298475.html
查看UITableViewCell的帮助文档我们可以看到它有两个属性highLighted、selected。这两者之间到底又怎么样的联系呢?当我们点击cell的时候都发生了什么呢?要达到这个目的,很简单我们只要自定义一个cell继承自UITableViewCell,然后重载它的以下两个方法:
- (void)setHighlighted:(BOOL)highlighted
animated:(BOOL)
- (void)setSelected:(BOOL)selected animated:(BOOL)
这两个方法一个是设置cell的高亮状态,另一个是设置cell的选中状态,我们只需要在这两个方法里面打印信息就可以看出点击cell时这些状态是怎么变化的了。当我们点击cell的时候,其实是先设置cell的高亮状态为YES,然后松手的时候再将cell的高亮状态设置为NO,接着才是设置cell的选中状态为YES,最后才会去调用delegate中的tableview:didSelectRowAtIndexPath:方法。
由此可见:cell的高亮状态是不能持久的,即tap的时候会变成高亮,松手的时候就会自动设置为非高亮状态。而cell的选中状态则是可以持久的,我们不去触发它改变状态,则选中状态就不会
所以自己遇到问题应该是:当cell被长按处于highlighted=Yes的状态下,隐藏或者关闭tableView会导致此状态始终存在(测试如此,如果有误可能操作或者其他问题,请留言指出),而每次默认显示都会将第一个cell处于selected状态,于是出现两个cell处于选中的图片状态。
刚开始想到的解决方法是:在每次显示tableView的时候,判断可见的cell的highlight状态,如果处于Yes,则调用-
(void)setHighlighted:(BOOL)highlighted
animated:(BOOL)将之重置为No,这个可以解决两个cell处于选装的图片情况,但是此时点击任意cell的状态,都会将刚才设置cell的highlight为No的cell,重新设置为selected状态,自己初步猜测是:app存储了此highlight和selected的对应状态,再次点击时,会继续刚才的cell的highlight动作结束,开始selected状态,所以总是会高亮之前的cell,此问题不知如何解决。
后来发现一个简易的方法:在每次重新显示UITableView的时候,可以调用一下reloadData,然后在初始化第一个cell的selected状态,就不会有之前的问题。
所以:UITableView reloadData 方法自己会初始化所有的data,以及他们的状态。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。IOS研究之UITabBarController隐藏tabBar以及addChildViewController - 推酷
IOS研究之UITabBarController隐藏tabBar以及addChildViewController
最近我所在的项目组对项目进行了一些基础组件的优化,其中有关于UITabBarController隐藏tabBar的问题感觉有必要总结下。
先来说说项目基本需求:整个项目由左侧栏和主视图组成,主视图主体是一个UITabBarController,下属几个嵌套了UINavigationController的UIViewController。
要求:当在页面上下滑动的时候,根据用户手势需要隐藏显示底部栏,也就是默认的UITabBarController的tabBar。
我在设计的时候是将左侧栏和主视图通过addChildViewController的方式添加到一个容器UIViewController中,并使用了UITabBarController自带的tabBar。隐藏显示tabBar是通过修改tabBar的frame来实现的。界面布局演示代码如下:对CoreAnimation不够清楚的可以看
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
UIViewController *parentController = [[UIViewController alloc] init];
SideBarViewController
*sideBarViewController = [[SideBarViewController alloc] init];//左侧栏 - 也是需要有弹出UIViewController的功能。
UINavigationController *sideBarNavController = [[UINavigationController alloc] initWithRootViewController: sideBarViewController];
sideBarNavController.navigationBarHidden = YES;
[parentController addChildViewController:sideBarNavController];//添加左侧栏
[parentController.view addSubview:sideBarNavController.view];
MyUITabBarController *tabBarController = [[MyUITabBarController alloc] init];//主体视图
//[parentController addChildViewController: tabBarController];//添加这句话,界面有问题
[parentController.view addSubview: tabBarController.view];
self.window.rootViewController = parentC
initWithFrame
mainScreen
applicationFrame
autorelease
UIViewController *
parentController
UIViewController
SideBarViewController&&*
sideBarViewController
SideBarViewController
//左侧栏 - 也是需要有弹出UIViewController的功能。&&
UINavigationController *
sideBarNavController
UINavigationController
initWithRootViewController
sideBarViewController
sideBarNavController
navigationBarHidden
parentController
addChildViewController
sideBarNavController
//添加左侧栏&&
parentController
addSubview
sideBarNavController
MyUITabBarController *
tabBarController
MyUITabBarController
//主体视图&&
//[parentController addChildViewController: tabBarController];//添加这句话,界面有问题&&
parentController
addSubview
tabBarController
rootViewController
parentController
其中MyUITabBarController中的演示代码如下:
UIViewController *
controller1
UIViewController
UINavigationController *
navigationController1
UINavigationController
initWithRootViewController
controller1
UIViewController *
controller2
UIViewController
UINavigationController *
navigationController2
UINavigationController
initWithRootViewController
controller2
navigationController1
navigationBarHidden
navigationController2
navigationBarHidden
//controller1.hidesBottomBarWhenPushed = YES;&&
//controller2.hidesBottomBarWhenPushed = YES;&&
controllers
arrayWithObjects
navigationController1
navigationController2
viewControllers
controllers
selectedIndex
在测试中发现:在iOS SDK6的环境下移动tabBar后,界面会留出空白,也就是说UITabBarController的tabBar的部分实际上是独占了该区域,即使强制将tabBar通过设置frame将tabBar移开,在该区域也不会显示其他内容。关于这个问题,github上有一个解决方案:
该方案代码很简洁:就是在移动tabBar之后,修改视图的frame大小,问题看似解决了。
我为什么没有使用UITabBarController_setHidden
似乎UITabBarController_setHidden能够解决问题,但在实际使用的时候发现一个问题,当使用pushViewController弹出一个UIViewController【配置hidesBottomBarWhenPushed=YES,页面弹出时tabBar隐藏】,接着popViewControllerAnimated弹回时,tabBar会自动显示并将所属页面的frame重新设置了。这样,设置页面frame的时机不好控制,另外这种方式在页面切换的时候也会有些不太美观的效果。
使用系统自带的tabBar或者navigationBar的好处是显而易见的,不过在本例中的情形(需要手势去隐藏显示底部栏),使用自定的tabBar反而不好处理。
尝试失败之后,我决定使用自定义的tabBar,想要自定义tabBar,一个问题就是怎么隐藏自带的tabBar。
如何隐藏UITabBarController自带的tabBar
网络上有方法:
self.tabBar.hidden = YES;
[self.tabBar removeFromSuperview];
这些确实能实现隐藏tabBar的功能,但是隐藏了之后在tabBar原有的位置没有填充上内容。正确的做法是:
将UITabBarController中的各个RootViewController进行如下设置:
self.homeViewController.hidesBottomBarWhenPushed = YES;
在我的工程中,还遇到了一个问题:即使设置了hidesBottomBarWhenPushed,在界面的底部还是留有一块没有内容的区域(正好是tabBar的区域)。经过查询,发现原因是在添加主体UITabBarController到容器UIViewController的时候,使用了addChildViewController的方式,将addChildViewController去掉,只保留addSubview的方式,一切运行正常。
addChildViewController怎么能影响到UITabBarController的tabBar
这个问题我暂时不清楚是由什么造成的。但说到这里了就谈谈我对addChildViewController这种方式的看法:使用addChildViewController的方式来处理本文描述的场景并没有什么好处。addChildViewController这种方式我感觉主要是为了能方便页面切换(使用transitionFromViewController方法),而本场景中,并不是“两个页面切换”,而是左侧栏和主体视图一直都存在,只是通过手势移开或者显示各自的view而已。
之前我都是只使用addSubview将左侧栏的view和主体view(都是UIController的view)依次添加到一个容器上,网络上有人说“[viewController.view addSubview:someOtherViewController.view];”这种方式其实对是UIViewController的误用,因为这么做“将不会触发被加入view hierarchy的view的controller的viewWillAppear:方法”。
已发表评论数()
&&登&&&陆&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见软件与服务//
隐藏的特性和解决之道
  当 iOS7 刚发布的时候,全世界的苹果开发人员都立马尝试着去编译他们的app,接着再花上数月的时间来修复任何出现的故障,甚至重做app。这样的结果,使得人们根本无暇去探究 iOS7 所带来的新东西。一些明显而细微的更新,比如说[NSArray firstObject],这个方法可追溯到 iOS4 时代,现在被提为公有API,除此之外,还有很多隐藏的特性等着我们去挖掘。
  平滑淡入淡出动画
  我这里要讨论的并非新的弹性动画APIs 或者 UIDynamics,而是一些更细微的东西。CALayer增加了两个新方法:allowsGroupOpacity和allowsEdgeAntialiasing。现在,组不透明度(group opacity)不再是什么新鲜的东西了。iOS会多次使用存在于 Info.plist 中的键UIViewGroupOpacity并可在应用程序范围内启用或禁用它。对于大多数apps而言,这(译注:启用)并非所期望的,因为它会降低整体性能。在 iOS7 中,用 SDK7 所链接的程序,这项属性默认是启用的。当它被启用时,一些动画将会变得不流畅,它也可以在layer层上被控制。
  一个有趣的细节,如果allowsGroupOpacity启用的话,_UIBackdropView(在UIToolbar或者UIPopoverView中的背景视图)不能对其模糊进行动画处理,所以当你做一个alpha转换时,你可能会临时禁用这项属性。因为这会降低动画体验,你可以回退到旧的方式然后在动画期间临时启用shouldRasterize。别忘了设置适当的rasterizationScale,否则在retina的设备上这些视图会成锯齿状。
  如果你想要复制的 Safari 显示所有选项卡时的动画,那么边缘抗锯齿属性将变得非常有用。
  阻塞动画
  一个小但非常有用的新方法[UIView performWithoutAnimation:]。它是一个简单的封装,先检查动画当前是否启用,然后禁止动画,执行块语句,最后重新启用动画。一个需要说明的地方是,它并不会阻塞基于 CoreAnimation 的动画。因此,不用急于将你的方法调用从:
  4[CATransaction begin];
  [CATransaction setDisableActions:YES];
  view.frame = CGRectMake(...);
  [CATransaction commit];
  替换为:
  3[UIView performWithoutAnimation:^{
  view.frame = CGRectMake(...);
  但是,绝大多数情况下这样也能工作的很好,只要你不直接处理CALayers。
  iOS7 中,我有很多代码路径(主要是 UITableViewCells)需要额外的保护,防止意外的动画,例如,如果一个弹窗的大小调整了,那么同时显示中的表视图将因为高度的变化而加载新的cell。我通常的做法是将整个 layoutSubviews 的代码包扎到一个动画块中:
  8- (void)layoutSubviews
  // Otherwise the popover animation could leak into our cells on iOS 7 legacy mode.
  [UIView performWithoutAnimation:^{
  [super layoutSubviews];
  _renderView.frame = self.
  处理长表视图
  UITableView 非常快速高效,除非你开始使用tableView:heightForRowAtIndexPath:,它会开始为你表中任意元素调用此方法,即便没有可视对象,就比如其内在的UIScrollView只是去获取正确的contentSize。此前有一些变通方法,但都不好用。iOS7 中,苹果公司终于承认这一问题,并添加tableView:estimatedHeightForRowAtIndexPath:,这个方法延迟了实际滚动时间成本的大部分。如果你不知道一个cell的大小,返回UITableViewAutomaticDimension即可。
  对于节头/尾(section headers/footers),现在也有类似的API了。
  UISearchDisplayController
  苹果的 search controller 使用了新的技巧来简化移动 search bar 到 navigation bar 的过程。启用 displaysSearchBarInNavigationBar 就可以了(除非你还要用到 scope bar,我只能说你真不幸)。我倒是很喜欢这么做,但比较遗憾的是,iOS7 上的 UISearchDisplayController 貌似被摧残的比较严重,尤其是iPad。苹果公司看上去像是没时间处理这个问题的样子(原文:Apple seems to have run out of time),对于显示的搜索结果并不会隐藏实际的表视图。在 iOS7 之前,这并没有问题,但是现在 searchResultsTableView 有一个透明的背景色,使它看上去相当糟糕。作为一种变通方法,你可以设置不透明色或者取道于富于技巧的手段来获得你所期望的。关于这个控件会出现各种各样的结果,当使用displaysSearchBarInNavigationBar时甚至不会展示搜索表视图。
  你的结果可能有所不同,但我是使用了一些手段来让displaysSearchBarInNavigationBar工作的:
  28- (void)restoreOriginalTableView
  if (PSPDFIsUIKitFlatMode() && self.originalTableView) {
  self.view = self.originalTableV
  - (UITableView *)tableView
  return self.originalTableView ?: [super tableView];
  - (void)searchDisplayController:(UISearchDisplayController *)controller
  didShowSearchResultsTableView:(UITableView *)tableView
  // HACK: iOS 7 requires a cruel workaround to show the search table view.
  if (PSPDFIsUIKitFlatMode()) {
  if (!self.originalTableView) self.originalTableView = self.tableV
  self.view = controller.searchResultsTableV
  controller.searchResultsTableView.contentInset = UIEdgeInsetsZ // Remove 64 pixel gap
  - (void)searchDisplayController:(UISearchDisplayController *)controller
  didHideSearchResultsTableView:(UITableView *)tableView
  [self restoreOriginalTableView];
  这里,别忘了在viewWillDisappear中调用restoreOriginalTableView,否则会发送crash。
  记住这是唯一的解决办法;可能有不少激进的方法不替换视图本身,但这个问题确实应该由苹果公司来修复。(TODO: RADAR!)
  UIWebView 使用了新的技巧来自动分页带paginationMode的网站。有一大堆与此功能相关的新属性:
  5@property (nonatomic) UIWebPaginationMode paginationMode NS_AVAILABLE_IOS(7_0);
  @property (nonatomic) UIWebPaginationBreakingMode paginationBreakingMode NS_AVAILABLE_IOS(7_0);
  @property (nonatomic) CGFloat pageLength NS_AVAILABLE_IOS(7_0);
  @property (nonatomic) CGFloat gapBetweenPages NS_AVAILABLE_IOS(7_0);
  @property (nonatomic, readonly) NSUInteger pageCount NS_AVAILABLE_IOS(7_0);
  现在而言,虽然这可能并非对于大多数网站都有用,但它肯定是生成简单的电子书阅读器或显示文本的一种更好的方式。加点乐子的话,请尝试将它设置为UIWebPaginationModeBottomToTop。
  会飞的 Popovers
  想知道为什么你的popovers疯了一样到处乱飞?在UIPopoverControllerDelegate协议中有一个新的代理方法使你能控制它:
  3- (void)popoverController:(UIPopoverController *)popoverController
  willRepositionPopoverToRect:(inout CGRect *)rect
  inView:(inout UIView **)view
  当popover锚点是指向一个UIBarButtonItem时,UIPopoverController会有一些动作,但如果你让它在一个view或者rect中显示,你可能就需要实现此方法并正常返回。一个花费了我相当长的时间来验证的问题――如果你通过改变preferredContentSize来动态调整你的popovers,那么这个方法就特别要求得以实现。苹果公司现在对改变popovers大小的请求更严格,如果没有预留足够的空间,popover将会到处移动。
  键盘支持
  苹果公司不只为我们提供了全新的framework用于游戏控制器,它也给了我们这些键盘爱好者一些提示!你会发现新定义的公用键像 UIKeyInputEscape 或 UIKeyInputUpArrow,可以使用所有新的 UIKeyCommand 类截查。在 iOS7 之前,只能通过一些难以言表的手段来处理键盘命令,现在,就让我们操起蓝牙键盘试试看我们能用这个做什么!
  开始之前,你需要对责任者链有个了解。你的 UIApplication 继承自 UIResponder,UIView 和 UIViewController 也是如此。如果你处理过 UIMenuItem 并且没有使用我的基于块的包装的话,那么你已经了解了这些。事件先被发送到最上层的响应者,然后一级级往下传递直到 UIApplication 。为了捕获按键命令,你需要告诉系统你关心哪些键命令(而不是全捕获)。为了完成这个,你需要重写keyCommands这个新属性:
  11- (NSArray *)keyCommands
  return @[[UIKeyCommand keyCommandWithInput:@"f"
  modifierFlags:UIKeyModifierCommand
  action:@selector(searchKeyPressed:)]];
  - (void)searchKeyPressed:(UIKeyCommand *)keyCommand
  // Respond to the event
  现在可别太激动,需要注意的是,这个方法只在键盘可见时有效(比如有类似 UITextView 这样的对象作为第一响应者时)。对于全局热键,你仍然需要用上面的方法。除却那些,这个路径还是很优雅的。不要覆盖类似 cmd-V 系统的快捷键,它会被自动映射为粘贴功能。
  还有一些新的预定义的响应行为如:
  2- (void)increaseSize:(id)sender NS_AVAILABLE_IOS(7_0);
  - (void)decreaseSize:(id)sender NS_AVAILABLE_IOS(7_0);
  它们分别对应着 cmd+ 和 cmd- 命令,用来放大/缩小内容。
  匹配键盘背景
  苹果公司终于公开了 UIInputView,其中提供了一种方式――使用UIInputViewStyleKeyboard来匹配键盘样式。这使得你可以编写自定义的键盘或者带默认样式的默认键盘扩展(工具条)。这个类以前就存在了,不过现在我们终于可以绕过私有API的方式来使用它了。
  如果 UIInputView 是一个 inputView 或者 inputAccessoryView 的根视图,它将只显示一个背景,否则它将是透明的。遗憾的是,这并不能让你实现一个未填充的分离态的键盘,但它仍然比用一个简单的 UIToolbar 要好。我还没看到苹果在何处使用这个新API,貌似它只作为一个 UIToolbar 使用在 Safari 上。
  了解你的网络
  虽然早在 iOS4 的时候,关于网络信息的大部分已经在 CTTelephony 暴露了,但它通常只用于特定场景并非十分有用。iOS7 中,苹果公司为其添加了一个方法,其中最有用的:currentRadioAccessTechnology。这个使你能知晓手机是处于较慢的GPRS还是高速的LTE或者介于其中。目前还没有方法得到连接速度(当然手机本身也无法获取这个),但是这足以用来优化一个下载管理器,让其在EDGE下不用尝试同时去下载6张图片了。
  现在还没有currentRadioAccessTechnology的相关文档,因此存在一些不正规或者错误的用法。当你想要获取当前网络信号值,你应当注册一个CTRadioAccessTechnologyDidChangeNotification通知而不应该去轮询这个属性。为了获取这些通知,你需要使用CTTelephonyNetworkInfo的一个实例,注意不要在通知中创建 CTTelephonyNetworkInfo 的实例,否则会 crash。
  在这个简单的例子中,我在block中捕获并持有了 telephonyInfo,大家可以忽略这个:
  9CTTelephonyNetworkInfo *telephonyInfo = [CTTelephonyNetworkInfo new];
  NSLog(@"Current Radio Access Technology: %@", telephonyInfo.currentRadioAccessTechnology);
  [NSNotificationCenter.defaultCenter addObserverForName:CTRadioAccessTechnologyDidChangeNotification
  object:nil
  queue:nil
  usingBlock:^(NSNotification *note)
  NSLog(@"New Radio Access Technology: %@", telephonyInfo.currentRadioAccessTechnology);
  当手机从edge环境到3G,log输出应该像这样:
  iOS7Tests[612:60b] Current Radio Access Technology: CTRadioAccessTechnologyEdge
  iOS7Tests[612:1803] New Radio Access Technology: (null)
  iOS7Tests[612:1803] New Radio Access Technology: CTRadioAccessTechnologyHSDPA
  苹果导出了所有字符串符号,因此可以很简单的比较和检测当前的网络信息。
  Core Foundation 和 Autorelease
  Core Foundation中出现了一个新的方法,它被用于私有调用已有数年时间:
  CFTypeRef CFAutorelease(CFTypeRef CF_RELEASES_ARGUMENT arg)
  它确实做了你所期望的事,让人费解的是苹果花了这么长时间才把它公开。ARC 下,大多数人在处理返回 Core Foundation 对象时是通过转换成对等的 NS 对象来完成的,如 NSDictionary,即便它只是一个 CFDictionaryRef 然后简单地 CFBridgingRelease() 。这样通常没问题,除非你返回的对等 NS 对象不可用时,如 CFBagRef。你要么使用 id,这样会失去类型安全性,要么你将你的方法重命名为 createMethod 并考虑所有的内存语义,最后使用 CFRelease。还有一些手段,比如这个,用 non-ARC-file 标签然后编译,但终归得使用CFAutorelease()。另外:不要编写使用苹果公司命名空间的代码,所有这些自定义的 CF-宏将来都会被打破的。
  图片解压缩
  当通过 UIImage 展示一张图时,在显示之前需要解压缩(除非源已经像素缓存了)。对于 JPG/PNG 文件这会占用相当可观的时间并会造成卡顿。iOS6 以前,通常是创建一个位图上下文,然后在其中画图来解决。(参见 AFNetworking 如何处理)。
  iOS7 开始,你可以使用kCGImageSourceShouldCacheImmediately:来强制图片在创建时立即解压缩:
  10+ (UIImage *)decompressedImageWithData:(NSData *)data
  CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
  CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, (__bridge CFDictionaryRef)@{(id)kCGImageSourceShouldCacheImmediately: @YES});
  UIImage *image = [UIImage imageWithCGImage:cgImage];
  CGImageRelease(cgImage);
  CFRelease(source);
  当我刚发现这一点时确实很兴奋,但事实并非如此。在我的测试中,发现当开启了即时缓存后性能有明显的降低。要么这个方法是在主线程中调用的(不太可能),感觉上性能更糟,因为它在方法copyImageBlockSetJPEG中锁住了,而同时在主线程中在显示非加密的图片所致。在我的程序中,我在主线程中加载小的预览图,在后台线程中加载大型图,使用了kCGImageSourceShouldCacheImmediately后小小的解压缩阻塞了主线程,同时在后台处理大量开销昂贵的操作。
  还有更多关于图片解压缩相关的却不是 iOS7 中的新东西,像kCGImageSourceShouldCache,它用来控制系统自动卸载解压缩的图片数据的能力。确保你将它设置为YES,否则所有的工作都将没有意义。有趣的是,苹果在64bit运行时的系统中将kCGImageSourceShouldCache的默认值从 NO 改为了 YES。
  盗版检查
  苹果添加了一个方式,通过 NSBunble 上的新方法appStoreReceiptURL来评估Lion系统上 App Store 的收据,同时也将其移植到了 iOS 上。这使得你可以检查你的应用是在被合法购买或者已经被破解了。检查收据还有一个重要的原因,它包含了初始购买日期,这点对于把你的应用从付费模型迁移到免费+应用内付费方式很有帮助意义。你可以根据这个初始购买日期来决定额外内容对于你的用户是免费的还是收费的。
  收据还允许你检查应用程序是否通过批量购买计划购买以及该许可证是否仍有效,有一个名为SKReceiptPropertyIsVolumePurchase的属性显示了该值。
  当你调用appStoreReceiptURL时,你需要特别注意,因为在 iOS6 上,它还是一个私有API,你应该在用户代码中先调用doesNotRecognizeSelector:,在调用前检查运行(基础)版本。在开发期间,这个方法返回的 URL 不会是指向一个文件。你可能需要使用 StoreKit 的SKReceiptRefreshRequest,这也是 iOS7 中的新东西,用它来下载证书。使用一个至少购买过一次的测试用户,否则它将没法工作:
  4// Refresh the Receipt
  SKReceiptRefreshRequest *request = [[SKReceiptRefreshRequest alloc] init];
  [request setDelegate:self];
  [request start];
  验证收据需要大量的代码。你需要使用OpenSSL和内嵌的苹果根证书,并且你还要了解一些基本的东西像是证书、PCKS容器以及ASN.1。这里有一些样例代码,但是你不应该让它这么简单――别只是拷贝现有的验证方法,至少做点修改或者编写你自己的,你应该不希望一个普通的补丁程序就能在数秒内瓦解你的努力吧。
  你绝对应该读读苹果的指南――验证 Mac App 商店收据,这里面的大多数都适用于 iOS。苹果在 WWDC2013 的 Session308 “Using Receipts to Protect Your Digital Sales” 中详述了“Grand Unified Receipt”的变动。
  Comic Sans MS
  iOS7 中,终于迎回了 Comic Sans MS。现在,它以可下载的字体被添加到 iOS6 中,但当时的字体列表很少也不见得多么有趣。在 iOS7 中苹果添加了不少字体,包括“famous”,它和 PT Sans 或 Comic Sans MS 有些类似。kCTFontDownloadableAttribute并没有在 iOS6 中声明,所以 iOS7 以前它并不真正可用,但苹果确是在 iOS6 的时候就已经做了私有声明了。
  字体列表是动态变化的,以后可能就会发生变动。苹果在 Tech Note HT5484 中罗列了一些可用的字体,但这个文档已经过时了,同时也不能反映 iOS7 的变化。
  这里显示了你该如何获取一个用CTFontDescriptorRef标示可下载的字体数组:
  3CFDictionary *descriptorOptions = @{(id)kCTFontDownloadableAttribute : @YES};
  CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)descriptorOptions);
  CFArrayRef fontDescriptors = CTFontDescriptorCreateMatchingFontDescriptors(descriptor, NULL);
  系统不会检查字体是否已存在于磁盘上而将直接返回同样的列表。另外,这个方法可能会启用网络并造成阻塞,你不应该在主线程中使用它。
  使用如下基于块的 API 来下载字体:
  4bool CTFontDescriptorMatchFontDescriptorsWithProgressHandler(
  CFArrayRef descriptors,
  CFSetRef mandatoryAttributes,
  CTFontDescriptorProgressHandler progressBlock)
  这个方法能操作网络并传递下载进度信息来调用你的progressBlock方法直到下载成功或者失败。参考苹果的 DownloadFont 样例看如何使用它。
  有一些值得注意的地方,这里的字体只在当前程序周期内有效,下次运行将被重新载入内存。因为字体存放在共享空间中,你不能依赖于它们是否可用。很有可能也不能保证的说,系统会清理这个目录,或者你的程序被拷贝到新的设备环境中,而这时又没有这个字体存在,同时当前处于没有网络的环境中。在 Mac 或是模拟器上,你能根据kCTFontURLAttribute获得字体的绝对路径,加载速度也会提升,但是在 iOS 上是不可能的,因为这个目录在你程序之外,你需要再次调用CTFontDescriptorMatchFontDescriptorsWithProgressHandler。
  你也可以注册新的kCTFontManagerRegisteredFontsChangedNotification通知来跟踪新字体在何时载入到了字体注册表中。你可以在 WWDC2013 的 Session223 “Using Fonts with TextKit”中查找更多信息。
  这还不够?
  没关系,iOS7 的新东西远不止如此!了解一下 NSHipster 你将明白语音合成相关的东西,base64、NSURLComponents、NSProgress、bar codes、reading lists 以及 CIDetectorEyeBlink。还有很多我们没有涵盖到的,比如苹果 iOS7 的 API 变化,iOS 指南的新东西以及 Foundation Release Notes(这些都是服务于 OS X的,但是代码都是共享的,也同样适用于 iOS)。很多方法都还没形成文档,等着你来探究和 blog。
关键词:iOS 7 隐藏 特性 解决 之道
责任编辑:贾玉
All Rights Reserved, Copyright , .cn渝ICP证B2-号 如有意见请与我们联系 powered by 天极内容管理平台CMS4i
京公网安备84号

我要回帖

更多关于 ios sdk是什么 的文章

 

随机推荐