细数AutoLayout以来UIView和UIViewController新增的相关API<转写>

细数AutoLayout以来UIView和UIViewController新增的相关API – UIViewController篇

UILayoutSupport

  1. @property(nonatomic,readonly,retain) id<UILayoutSupport> topLayoutGuide NS_AVAILABLE_IOS(7_0);
  2. @property(nonatomic,readonly,retain) id<UILayoutSupport> bottomLayoutGuide NS_AVAILABLE_IOS(7_0);
  3. @protocol UILayoutSupport <NSObject>
  4. @property(nonatomic,readonly) CGFloat length;
  5. @end

从iOS 7以来,当我们的视图控制器结构中有NavigationBar,TabBar或者ToolBar的时候,它们的translucent属性的默认值改为了YES,并且当前的ViewController的高度会是整个屏幕的高度。(比如一个场景:拖动TableView的时候,上面的NavigationBar能够透过去看到TableView的内容。)

为了确保我们的视图不被这些Bar覆盖,我们可以在我们AutoLayout布局中使用topLayoutGuide和bottomLayoutGuide这两个属性。像这样:

  1. NSDictionary *views = @{"topLayoutGuide" : self.topLayoutGuide, @"myLabel" : myLabel};
  2. [NSLayoutConstraint constraintsWithVisualFormat:@"V:[topLayoutGuide]-[myView]" options:0 metrics:nil views:views]

这个时候我们的视图就不会被Bar所覆盖,显示在了Bar下方:

并且使用这个属性布局时,在traitCollection改变时(旋转屏幕),它的值也会动态变化。上述代码,在横屏情况下,navigationbar高度变了之后,仍然能够正确显示。

这两个guides的计算方式如下:

topLayoutGuide是通过计算 View Controller->View->Top 到 覆盖这个View最下层的那个Bar(像Navigation Bar) -> Bottom 的距离
bottomLayoutGuide是通过计算 View Controller->View->Bottom 到 覆盖这个View上层那个Bar(像Tab bar) -> Top 的距离

如果我们不使用AutoLayout布局,我们也可以通过Guide的length属性获得相应的距离。我们应该在-viewDidLayoutSubviews或者-layoutSubviews调用super之后,再去获得length这个值,以确保正确。

UIConstraintBasedLayoutCoreMethods

  1. - (void)updateViewConstraints NS_AVAILABLE_IOS(6_0);

UIViewController中也新增了一个更新布局约束的方法,在AutoLayout UIView相关API的笔记中,详细讲述了UIView的一组更新布局约束的方法。

这个方法默认的实现是调用对应View的 -updateConstraints 。ViewController的View在更新视图布局时,会先调用ViewController的updateViewConstraints 方法。我们可以通过重写这个方法去更新当前View的内部布局,而不用再继承这个View去重写-updateConstraints方法。我们在重写这个方法时,务必要调用 super 或者 调用当前View的 -updateConstraints 方法。

UITraitEnvironment

又一次看到了UITraitEnvironment协议,在UIKit Framework中,有四个类支持这个协议,分别是UIScreen, UIViewController,UIView 和 UIPresentationController。所以当视图的traitCollection改变时,UIViewController能够捕获到这个消息,并做对应处理的。 更多解释可以参考上一篇文章详解UICoordinateSpace和UIScreen在iOS 8上的坐标问题。

关于Size Class和UITraitCollection的概念可参考如下链接:

WWDC 2014 Session笔记 - iOS界面开发的大一统 From: onecat’s Blog

iOS8 Size Classes的理解与使用 From: Joywii’s Blog

另外,UIViewController还另外提供了以下两个方法:

  1. - (void)setOverrideTraitCollection:(UITraitCollection *)collection forChildViewController:(UIViewController *)childViewController NS_AVAILABLE_IOS(8_0);
  2. - (UITraitCollection *)overrideTraitCollectionForChildViewController:(UIViewController *)childViewController NS_AVAILABLE_IOS(8_0);

我们可以通过调用ViewController的setOverrideTraitCollection方法为它的ChildViewController重新设置traitCollection的值。一般情况下traitCollection值从父controller传到子controller是不做修改的。当我们自己实现一个容器Controller的时候,我们可以使用这个方法进行调整。

相对的,我们可以通过overrideTraitCollectionForChildViewController方法获得ChildViewController的traitCollection值。

UIContentContainer

iOS 8上随着Size Class概念的提出,UIViewController支持了UIContentContainer这样一组新的协议:

  1. - (void)systemLayoutFittingSizeDidChangeForChildContentContainer:(id <UIContentContainer>)container NS_AVAILABLE_IOS(8_0);
  2. - (CGSize)sizeForChildContentContainer:(id <UIContentContainer>)container withParentContainerSize:(CGSize)parentSize NS_AVAILABLE_IOS(8_0);
  3. - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator NS_AVAILABLE_IOS(8_0);
  4. - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator NS_AVAILABLE_IOS(8_0);

UIViewController对这组协议提供了默认的实现。我们自定义ViewController的时候可以重写这些方法来调整视图布局,比如我们可以在这些方法里调整ChildViewControler的位置。当我们重写这些协议方法时,我们通常都去调用 super。

viewWillTransitionToSize: ViewController的View的size被他的Parent Controller改变时,会触发这个方法。(比如rootViewController在它的window旋转的时候)。我们在重写这个方法时,确保要调用super,来保证size改变的这条消息能够正常传递给它的Views或者ChildViewControllers。

willTransitionToTraitCollection: 当ViewController的traitCollection的值将要改变时会调用这个方法。这个方法是在 UITraitEnvironment协议方法 traitCollectionDidChange:之前被调用。我们在重写这个方法时,也要确保要调用super来保证消息的传递。比如,我们可以像这样在traitCollection值改变时,对视图做对应的动画进行调整:

  1. - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection
  2. withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
  3. {
  4. [super willTransitionToTraitCollection:newCollection
  5. withTransitionCoordinator:coordinator];
  6. [coordinator animateAlongsideTransition:^(id <UIViewControllerTransitionCoordinatorContext> context) {
  7. if (newCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
  8. } else {
  9. }
  10. [self.view setNeedsLayout];
  11. } completion:nil];
  12. }

sizeForChildContentContainer:一个容器ViewController可以使用这个方法设置ChildViewController的size。当容器ViewControllerviewWillTransitionToSize:withTransitionCoordinator:被调用时(我们重写这个方法时要调用Super),sizeForChildContentContainer方法将会被调用。然后我们可以把需要设置的size发送给ChildViewController。当我们设置的这个size和当前ChildViewController的size一样,那么ChildViewController的viewWillTransitionToSize方法将不会被调用。

sizeForChildContentContainer默认的实现是返回 parentSize。

systemLayoutFittingSizeDidChangeForChildContentContainer:当满足如下情况,这个方法会被调用:

当前ViewController没有使用AutoLayout布局
ChildrenViewController的View使用了AutoLayout布局
ChildrenViewController View -systemLayoutSizeFittingSize:方法返回的值改变(View由于内容的变化,size也出现了变化)

preferredContentSize

  1. // From UIContentContainer Protocol
  2. @property (nonatomic, readonly) CGSize preferredContentSize NS_AVAILABLE_IOS(8_0);
  3. - (void)preferredContentSizeDidChangeForChildContentContainer:(id <UIContentContainer>)container NS_AVAILABLE_IOS(8_0);
  4. // From UIViewController
  5. @property (nonatomic) CGSize preferredContentSize NS_AVAILABLE_IOS(7_0);

preferredContentSize在UIContentContainer协议中是只读的,对应的UIViewController有可写的版本。我们可以使用preferredContentSize来设置我们期望的ChildViewController的界面大小。举个例子,如果应用中使用的popOver大小会发生变化,iOS7之前我们可以用contentSizeForViewInPopover来调整。iOS7开始这个API被废弃,我们可以使用preferredContentSize来设置。

当一个容器ViewController的ChildViewController的这个值改变时,UIKit会调用preferredContentSizeDidChangeForChildContentContainer这个方法告诉当前容器ViewController。我们可以在这个方法里根据新的Size对界面进行调整。

总结
UIViewController到目前为止(iOS 8.1), 关于布局的API最大的变化是iOS8中新增支持的两组协议:UITraitEnvironment 和 UIContentContainer。我们可以在学习中通过Demo实现这些协议,来观察ViewController中这些方法最终被调用的时机。



细数AutoLayout以来UIView和UIViewController新增的相关API--UIView篇

iOS8上关于UIView的Margin新增了3个APIs:

  1. @property (nonatomic) UIEdgeInsets layoutMargins NS_AVAILABLE_IOS(8_0);
  2. @property (nonatomic) BOOL preservesSuperviewLayoutMargins NS_AVAILABLE_IOS(8_0);
  3. - (void)layoutMarginsDidChange NS_AVAILABLE_IOS(8_0);

在iOS 8中,可以使用layoutMargins去定义view之间的间距,该属性只对AutoLayout布局生效。

因此AutoLayout中NSLayoutAttribute的枚举值有了相应的更新:

  1. NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0),
  2. NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0),
  3. NSLayoutAttributeTopMargin NS_ENUM_AVAILABLE_IOS(8_0),
  4. NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0),
  5. NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0),
  6. NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0),
  7. NSLayoutAttributeCenterXWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),
  8. NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),

通过在Xcode中测试打印,发现UIView默认的layoutMargins的值为 {8, 8, 8, 8},我们可以通过修改这个值来改变View之间的距离。

在我们改变View的layoutMargins这个属性时,会触发- (void)layoutMarginsDidChange这个方法。我们在自己的View里面可以重写这个方法来捕获layoutMargins的变化。在大多数情况下,我们可以在这个方法里触发drawing和layout的Update。

preservesSuperviewLayoutMargins这个属性默认是NO。如果把它设为YES,layoutMargins会根据屏幕中相关View的布局而改变。举个例子:

如上图,有三个View,其中蓝色View的layoutMargins设为 UIEdgeInsetsMake(50, 50, 50, 50),黄色View的layoutMargins设为 UIEdgeInsetsMake(10, 10, 10, 10)。对黄色View的布局约束代码如下:

  1. [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0];
  2. [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeight multiplier:0.5 constant:0.0];
  3. [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0];
  4. [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];

对黑色View的布局代码如下:

  1. [NSLayoutConstraint constraintWithItem:blackView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:yellowView attribute:NSLayoutAttributeTrailingMargin multiplier:1.0 constant:0.0];
  2. [NSLayoutConstraint constraintWithItem:blackView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:yellowView attribute:NSLayoutAttributeLeadingMargin multiplier:1.0 constant:0.0];
  3. [NSLayoutConstraint constraintWithItem:blackView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:yellowView attribute:NSLayoutAttributeTopMargin multiplier:1.0 constant:0.0];
  4. [NSLayoutConstraint constraintWithItem:blackView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:yellowView attribute:NSLayoutAttributeBottomMargin multiplier:1.0 constant:0.0];

在preservesSuperviewLayoutMargins默认为NO的情况下,显示效果就和上图一样(间距为10)。当设置黄色View的preservesSuperviewLayoutMargins为YES时,将会获得如下效果(间距为50):

UIConstraintBasedLayoutInstallingConstraints

  1. @interface UIView (UIConstraintBasedLayoutInstallingConstraints)
  2. - (NSArray *)constraints NS_AVAILABLE_IOS(6_0);
  3. - (void)addConstraint:(NSLayoutConstraint *)constraint NS_AVAILABLE_IOS(6_0);
  4. - (void)addConstraints:(NSArray *)constraints NS_AVAILABLE_IOS(6_0);
  5. - (void)removeConstraint:(NSLayoutConstraint *)constraint NS_AVAILABLE_IOS(6_0);
  6. - (void)removeConstraints:(NSArray *)constraints NS_AVAILABLE_IOS(6_0);
  7. @end

以上这五个API中,第一个是返回当前View中所有的constraints。后面四个方法即将被废弃,应该使用NSLayoutConstraint类中activateConstraint相关方法替代。

UIConstraintBasedLayoutCoreMethods

  1. @interface UIView (UIConstraintBasedLayoutCoreMethods)
  2. - (void)updateConstraintsIfNeeded NS_AVAILABLE_IOS(6_0);
  3. - (void)updateConstraints NS_AVAILABLE_IOS(6_0);
  4. - (BOOL)needsUpdateConstraints NS_AVAILABLE_IOS(6_0);
  5. - (void)setNeedsUpdateConstraints NS_AVAILABLE_IOS(6_0);
  6. @end

setNeedsUpdateConstraints : 当一个自定义的View某一个属性的改变可能影响到界面布局,我们应该调用这个方法来告诉布局系统在未来某个时刻需要更新。系统会调用updateConstraints去更新布局。

updateConstraints :自定义View时,我们应该重写这个方法来设置当前view局部的布局约束。重写这个方法时,一定要调用[super updateConstraints]。

needsUpdateConstraints :布局系统使用这个返回值来确定是否调用updateConstraints

updateConstraintsIfNeeded :我们可以调用这个方法触发update Constraints的操作。在needsUpdateConstraints返回YES时,才能成功触发update Constraints的操作。我们不应该重写这个方法。

Auto Layout的布局过程是 update constraints(updateConstraints)-> layout Subviews(layoutSubViews)-> display(drawRect) 这三步不是单向的,如果layout的过程中改变了constrait, 就会触发update constraints,进行新的一轮迭代。我们在实际代码中,应该避免在此造成死循环。

UIConstraintBasedCompatibility

  1. @interface UIView (UIConstraintBasedCompatibility)
  2. - (BOOL)translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0);
  3. - (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag NS_AVAILABLE_IOS(6_0);
  4. + (BOOL)requiresConstraintBasedLayout NS_AVAILABLE_IOS(6_0);
  5. @end

默认情况下,View的autoresizing工作会根据当前位置自动设置约束。我们在使用代码写自己的约束布局代码时,必须设置当前View的translatesAutoresizingMaskIntoConstraints为NO,否则无法正常运作。IB默认是NO。

requiresConstraintBasedLayout :我们应该在自定义View中重写这个方法。如果我们要使用Auto Layout布局当前视图,应该设置为返回YES。

UIConstraintBasedLayoutLayering

  1. - (CGRect)alignmentRectForFrame:(CGRect)frame NS_AVAILABLE_IOS(6_0);
  2. - (CGRect)frameForAlignmentRect:(CGRect)alignmentRect NS_AVAILABLE_IOS(6_0);
  3. - (UIEdgeInsets)alignmentRectInsets NS_AVAILABLE_IOS(6_0);

AutoLayout并不会直接操作View的Frame,但是视图的alignment rect是起作用的。视图的默认alignmentRectInsets值就是(0,0,0,0)。

我们可以简单的对当前View设置用来布局的矩形,比如:

我们有一个自定义icon类型的Button,但是icon的大小比我们期望点击的Button区域要小。这个时候我们可以重写alignmentRectInsets,把icon放在适当的位置。

大多数情况下重写alignmentRectInsets这个方法可以满足我们的工作。如果需要更加个性化的修改,我们可以重写alignmentRectForFrame和frameForAlignmentRect这两个方法。比如我们不想减去视图固定的Insets,而是需要基于当前frame修改alignment rect。在重写这两个方法时,我们应该确保是互为可逆的。

Base line

  1. - (UIView *)viewForBaselineLayout NS_AVAILABLE_IOS(6_0);

当我们在使用布局约束中NSLayoutAttributeBaseline属性时,系统会默认返回当前视图的底部作为baseline。我们可以重写上述方法,但必须返回的是当前视图中的子视图。

Intrinsic Content Size

  1. UIKIT_EXTERN const CGFloat UIViewNoIntrinsicMetric NS_AVAILABLE_IOS(6_0);
  2. - (CGSize)intrinsicContentSize NS_AVAILABLE_IOS(6_0);
  3. - (void)invalidateIntrinsicContentSize NS_AVAILABLE_IOS(6_0);
  4. - (UILayoutPriority)contentHuggingPriorityForAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
  5. - (void)setContentHuggingPriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
  6. - (UILayoutPriority)contentCompressionResistancePriorityForAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
  7. - (void)setContentCompressionResistancePriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);

通过重写intrinsicContentSize可以设置当前视图显示特定内容时的大小。比如我们设置一个自定义View,View里面包含一个Label显示文字,为了设置当前View在不同Size Class下内容的大小,我们可以这样:

  1. - (CGSize)intrinsicContentSize
  2. {
  3. CGSize size = [label intrinsicContentSize];
  4. if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact) {
  5. size.width += 4.0f;
  6. } else {
  7. size.width += 40.0f;
  8. }
  9. if (self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
  10. size.height += 4.0;
  11. } else {
  12. size.height += 40.0;
  13. }
  14. return size;
  15. }

当有任何会影响这个Label内容大小的事件发生时,我们应该调用invalidateIntrinsicContentSize:

  1. label.text = @"content update"
  2. [self invalidateIntrinsicContentSize];
  3. // 或者比如当前视图Size Class改变的时候
  4. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
  5. {
  6. [super traitCollectionDidChange:previousTraitCollection];
  7. if ((self.traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass)
  8. || (self.traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass)) {
  9. [self invalidateIntrinsicContentSize];
  10. }
  11. }

不是所有的视图都有 intrinsicContentSize, UIView默认情况下就返回的是 UIViewNoIntrinsicMetric。只有当视图中需要根据内部内容进行调整大小时,我们才需要用到 intrinsicContentSize。

当视图大小在变化时,我们可以使用上面最后四个API来设置视图的压缩或者放大的方式。

  1. typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
  2. UILayoutConstraintAxisHorizontal = 0,
  3. UILayoutConstraintAxisVertical = 1
  4. };

上面最后四个API主要是通过修改水平或者垂直方向的优先级来实现视图是基于水平缩小(放大)还是垂直缩小(放大)。当我们的视图需要根据内部内容进行调整大小时,我们应该使用上述方法为当前视图设置初始值。而不应该重写这几个方法。

UIConstraintBasedLayoutFittingSize

  1. UIKIT_EXTERN const CGSize UILayoutFittingCompressedSize NS_AVAILABLE_IOS(6_0);
  2. UIKIT_EXTERN const CGSize UILayoutFittingExpandedSize NS_AVAILABLE_IOS(6_0);
  3. @interface UIView (UIConstraintBasedLayoutFittingSize)
  4. - (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize NS_AVAILABLE_IOS(6_0);
  5. - (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize withHorizontalFittingPriority:(UILayoutPriority)horizontalFittingPriority verticalFittingPriority:(UILayoutPriority)verticalFittingPriority NS_AVAILABLE_IOS(8_0);
  6. @end

上面两个API可以获得当前使用AutoLayout视图的size。其中targetSize可以传入UILayoutFittingCompressedSize或者UILayoutFittingExpandedSize,分别对应的是最小情况下可能的Size和最大情况下可能的Size。

UIConstraintBasedLayoutDebugging

  1. - (NSArray *)constraintsAffectingLayoutForAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
  2. - (BOOL)hasAmbiguousLayout NS_AVAILABLE_IOS(6_0);
  3. - (void)exerciseAmbiguityInLayout NS_AVAILABLE_IOS(6_0);

第一个API可以获得视图在不同方向上所有的布局约束。

hasAmbiguousLayout :可以知道当前视图的布局是否会有歧义。这里有一个私有API _autolayoutTrace可以获得整个视图树的字符串。

  1. #ifdef DEBUG
  2. NSLog(@"%@", [self performSelector:@selector(_autolayoutTrace)]);
  3. #endif

exerciseAmbiguityInLayout :这个方法会随机改变视图的layout到另外一个有效的layout。这样我们就可以很清楚的看到哪一个layout导致了整体的布局约束出现了错误,或者我们应该增加更多的布局约束。

我们应该让上面的四个方法只在DEBUG环境下被调用。

新增支持 UITraitEnvironment Protocol

  1. @protocol UITraitEnvironment <NSObject>
  2. @property (nonatomic, readonly) UITraitCollection *traitCollection;
  3. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection;
  4. @end

iOS 8 上新增了Size Class的概念,其中UITraitCollection类用来描述不同Size大小。关于Size Class和UITraitCollection的概念可参考如下链接:http://joywii.github.io/blog/2014/09/24/ios8-size-classesde-li-jie-yu-shi-yong/

UIView实现了这个协议,我们可以获得当前View的traitCollection,从而得知当前View处于什么样的Size Class下。并且当traitCollection有变化时,我们可以通过重写traitCollectionDidChange知道该事件的触发。默认情况下,这个方法什么都不执行。

traitCollection的变化是从UIScreen开始被触发,并且逐层往下传递的,具体如下:

UIScreen -> UIWindow -> UIViewController -> ChildViewControllers -> View -> Subviews

关于这一点,我在详解UICoordinateSpace和UIScreen在iOS 8上的坐标问题一文中有做详细解释。

总结
UIView到目前为止(iOS 8.1),所有增加的关于AutoLayout的API请参考上述文章。进一步对这些API理解可以让我们写出更健壮的布局代码。

本文转自ChunTips

时间: 2024-10-25 18:54:31

细数AutoLayout以来UIView和UIViewController新增的相关API<转写>的相关文章

细数AutoLayout以来UIView和UIViewController新增的相关API

UILayoutSupport 1 @property(nonatomic,readonly,retain) id topLayoutGuide NS_AVAILABLE_IOS(7_0); 2 @property(nonatomic,readonly,retain) id bottomLayoutGuide NS_AVAILABLE_IOS(7_0); 3 4 @protocol UILayoutSupport 5 @property(nonatomic,readonly) CGFloat l

AutoLayout以来UIView和UIViewController新增的相关API

http://www.itjhwd.com/autolayout-uiview-uiviewcontroller-api/ UILayoutSupport Java 从iOS 7以来,当我们的视图控制器结构中有NavigationBar,TabBar或者ToolBar的时候,它们的translucent属性的默认值改为 了YES,并且当前的ViewController的高度会是整个屏幕的高度.(比如一个场景:拖动TableView的时候,上面的 NavigationBar能够透过去看到Table

迄今最安全的MySQL?细数5.7那些惊艳与鸡肋的新特性(上)【转载】

转自: DBAplus社群 http://www.toutiao.com/m5762164771/ 迄今最安全的MySQL?细数5.7那些惊艳与鸡肋的新特性(上) - 今日头条(TouTiao.com)http://toutiao.com/a6300616158581604609/?tt_from=mobile_qq&utm_campaign=client_share&app=news_article&utm_source=mobile_qq&iid=4592472790&

细数2014年成长

冬天的来临,让我的心很冷,不想动,不想思考,不想说话,今年剩下的一些日子,我想也就这样了,不会再有什么变化了.打开文档,开始记录今年,展望明年.记录是为了抛弃过去一切,又想未来某天还能拾起,所以把它尘封在笔记里.之后就可让脑中的一切随风消散,没有任何思想负担,放空的心就能接纳更多新的内容. 细数2014年的成长  成长主要在意识形态上,至于技术,越来越难静下心来学了. 1.彻底离弃网络游戏 放弃网络游戏,开始把人生当做游戏.这个游戏只有一次机会,不能死,不能走错路,每一次选择都要经过深思熟虑.和

细数人体器官仿生,还有哪些可开发的

太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 人体器官列表(后续'借'张人体图过来 -- 读书人的事情,不能叫偷,叫窃,谐个音,就叫借了) 1.眼:摄像头: 2.耳:mic: 3.口:音箱或耳

再回首:细数存储设备的前世今生-转

我们如何迎头赶上? 据IDC统计,今年全球数据总量将达到2.16ZB,预计将在2016年增长到3.77ZB.随着数据量的不断增长,对数据存储的要求也越来越高,不过无须担心,相关的存储技术也已经迎头赶上. 数据存储技术是发展最快的电子技术.磁带,硬盘和固态硬盘的容量大约以每12到18个月就会增加一倍. 如今的台式机硬盘容量已经高达4TB~5TB.这足以装下1万张照片或562小时的高清视频.希捷表示,到2020年热辅助磁记录技术(HAMR)会带来60TB硬盘,这一容量足以存储12万张照片或6750小

细数空格缩进在开发中的坑

没错,这是一篇火药文.网上流传的各种编程规范几乎青一色都是说用空格代替Tab,其理由几乎都是“这是唯一能保证在所有环境下获得一致展现的方法”. 那我想问一句,你们到底能要多少种环境要看代码??? 1.用Windows自带的记事本?那我只能说,你继续装,看你什么时候才能完成得了任务.2.连接到Linux服务器上使用VI或者VIM?我也只能说只有改服务器的配置文件的时候才会这样做吧,而且如果是配置文件比较复杂也是下载下来用Notepad++改清晰很多好伐,比如Aapche的配置文件在Notepad+

年华细数 谁的幸福不知归途

年华细数  谁的幸福不知归途 文   沫子也 他今年大一,他喜欢她. 有别于一见钟情,他对她的喜欢更趋向于百转千回,这个时候的她,刚和男朋友分手,念大二.之所以说百转千回,还因为后来一起吃饭的时候,她问他彼此是什么时候见的第一面,他支吾半天竟想不起来,第一次见面,大抵没给他留下多少印象.只是在全社大会的时候,不期然的,她就坐在了他的旁边.他注意到她的眼神,月光一样清亮.散会后,报名参加活动的表格上,他没细想星期四自己有课,就把她填的兴趣组合唱班给照搬抄了下来.慢慢的因为工作关系,他们是朋友. 如

从VGA到GPU!细数二十年显卡发展历程

VGA有很多层涵义,本来是用于代表一个分辨率(您可能不了解VGA,但应该知道QVGA代表什么),随后被普遍称为显示输出接口.为了输出VGA分辨 率.提供VGA输出接口,显卡和VGA就有了不解之缘,显卡被称为VGA Card是有历史原因的,如果您对此感兴趣的话,请慢慢看: ● 什么是VGA? VGA,Video Graphic  Array,视频图形阵列,表示一组点阵图形,长640像素宽480像素,最初能够输出640×480分辨率的接口叫做D-Sub,也被称作VGA接口, 它是一个15针的梯形插头