为App适配iOS11

TableView

当tableview的style为grouped的时候,会出现每个section之间有间距。

官方解析:Link on iOS 11, all estimated heights default to UITableViewAutomaticDimension Headers, footers, and cells use self-sizing by default.

- 解决方案:

如果开发者不想用这个新特性,可以在代理方法里面设置具体的高度,然后设置

tableView.estimatedRowHeight = 0 
tableView.estimatedSectionHeaderHeight = 0 
tableView.estimatedSectionFooterHeight = 0

TitleView

因为iOS11 的navbar的大标题和搜索栏的新特性,navbar的子视图发生了变化。 如果没有给出明确的长宽,就会出现Zero-size的出现,就是说titleview不见了,或者各种奇怪的事情出现。

- 解决方案:

  1. 给出指定的长宽,和子view设置好对应的约束。
  2. 或者重写intrinsicContentSize方法,设置成UILayoutFittingExpandedSize,让它自己自动扩展。
@available(iOS 6.0, *)
public let UIViewNoIntrinsicMetric: CGFloat

// Size To Fit

@available(iOS 6.0, *)
public let UILayoutFittingCompressedSize: CGSize
@available(iOS 6.0, *)
public let UILayoutFittingExpandedSize: CGSize

如果设置成扩展的话titleView和两边的item粘在一起了,所以需要做一下子视图的布局。

题外话: iOS6有一个API,systemLayoutSizeFitting,可以根据view的约束计算出对应的大小,具体可以看API文档。

Safe Area

这个主要影响用到mj的列表页面,和隐藏navbar的列表页面。

Safe Area是系统自己算的,系统会根据state bar的高度,navbar、tabbar是否透明(isTranslucent)。

每个view都有一个叫safeAreaInsets的属性(get only)。 如果开发者需要更改view的safe area 可以在controller设置additionalSafeAreaInsets去属性去弄。

例如:

带有navbar,和tabbar的页面。

controller.view.safeAreaInsets 为 UIEdgeInsets(top: 64.0, left: 0.0, bottom: 49.0, right: 0.0)

如果想改为(20,0,49,0)只需要做如下操作。

controller.view.additionalSafeAreaInsets = UIEdgeInsets(top: -44.0, left: 0.0, bottom: -49.0, right: 0.0)

其实无论设置成(-20000,0,0,0)也是最终得到的(20,0,49,0),还有就是无论设置bottom为-49还是其他的值,都无法抵消tabbar的高度,也就是说系统不允许我们去缩减bottom的值,可能是因为iPhoneX的底部虚拟home键。

view.safeAreaInsets是影响其子ScrollView的adjustedContentInset。 ScrollView会根据contentInsetAdjustmentBehavior属性去设置 adjustedContentInset。

public enum UIScrollViewContentInsetAdjustmentBehavior : Int {
    case automatic // Similar to .scrollableAxes, but for backward compatibility will also adjust the top & bottom contentInset when the scroll view is owned by a view controller with automaticallyAdjustsScrollViewInsets = YES inside a navigation controller, regardless of whether the scroll view is scrollable

    case scrollableAxes // Edges for scrollable axes are adjusted (i.e., contentSize.width/height > frame.size.width/height or alwaysBounceHorizontal/Vertical = YES)

    case never // contentInset is not adjusted

    case always // contentInset is always adjusted by the scroll view's safeAreaInsets
}
  1. UIScrollViewContentInsetAdjustmentAutomatic:如果scrollview在一个automaticallyAdjustsScrollViewContentInset = YES的controller上,并且这个Controller包含在一个navigation controller中,这种情况下会设置在top & bottom上 adjustedContentInset = safeAreaInset + contentInset不管是否滚动。其他情况下与UIScrollViewContentInsetAdjustmentScrollableAxes相同
  2. UIScrollViewContentInsetAdjustmentScrollableAxes: 在可滚动方向上adjustedContentInset = safeAreaInset + contentInset,在不可滚动方向上adjustedContentInset = contentInset;依赖于scrollEnabled和alwaysBounceHorizontal / vertical = YES,scrollEnabled默认为yes,所以大多数情况下,计算方式还是adjustedContentInset = safeAreaInset + contentInset
  3. UIScrollViewContentInsetAdjustmentNever: adjustedContentInset = contentInset
  4. UIScrollViewContentInsetAdjustmentAlways: adjustedContentInset = safeAreaInset + contentInset

- 使用MJ的列表页的适配方案

if #available(iOS 11, *) {
    t.contentInset.top += kTopBarHeight
    t.contentInset.bottom += kHomeBarHeight // 如果列表底部没有任何toolbar的需要添加,为了适配iPhone X
    t.contentInsetAdjustmentBehavior = .never
}

底层API命名改变

例如我使用一些第三方库的时候,它们有用到一些API如check_compile_time() 在iOS11里面的命名改变为__Check_Compile_Time()。

-解决方案:

找到对应的头文件,搜索旧的API一般都有说明的。

/*
 *	For time immemorial, Mac OS X has defined version of most of these macros without the __ prefix, which
 *	could collide with similarly named functions or macros in user code, including new functionality in
 *	Boost and the C++ standard library.
 *
 *  macOS High Sierra and iOS 11 will now require that clients move to the new macros as defined above.
 *
 *  If you would like to enable the macros for use within your own project, you can define the
 *  __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES macro via an Xcode Build Configuration.
 *  See "Add a build configuration (xcconfig) file" in Xcode Help. 
 *
 *  To aid users of these macros in converting their sources, the following tops script will convert usages
 *  of the old macros into the new equivalents.  To do so, in Terminal go into the directory containing the
 *  sources to be converted and run this command.
 *
    find . -name '*.[c|cc|cp|cpp|m|mm|h]' -print0 |  xargs -0 tops -verbose 
      replace "check(<b args>)" with "__Check(<args>)" 
      replace "check_noerr(<b args>)" with "__Check_noErr(<args>)" 
      replace "check_noerr_string(<b args>)" with "__Check_noErr_String(<args>)" 
      replace "check_string(<b args>)" with "__Check_String(<args>)" 
      replace "require(<b args>)" with "__Require(<args>)" 
      replace "require_action(<b args>)" with "__Require_Action(<args>)" 
      replace "require_action_string(<b args>)" with "__Require_Action_String(<args>)" 
      replace "require_noerr(<b args>)" with "__Require_noErr(<args>)" 
      replace "require_noerr_action(<b args>)" with "__Require_noErr_Action(<args>)" 
      replace "require_noerr_action_string(<b args>)" with "__Require_noErr_Action_String(<args>)" 
      replace "require_noerr_string(<b args>)" with "__Require_noErr_String(<args>)" 
      replace "require_string(<b args>)" with "__Require_String(<args>)" 
      replace "verify(<b args>)" with "__Verify(<args>)" 
      replace "verify_action(<b args>)" with "__Verify_Action(<args>)" 
      replace "verify_noerr(<b args>)" with "__Verify_noErr(<args>)" 
      replace "verify_noerr_action(<b args>)" with "__Verify_noErr_Action(<args>)" 
      replace "verify_noerr_string(<b args>)" with "__Verify_noErr_String(<args>)" 
      replace "verify_string(<b args>)" with "__Verify_String(<args>)" 
      replace "ncheck(<b args>)" with "__nCheck(<args>)" 
      replace "ncheck_string(<b args>)" with "__nCheck_String(<args>)" 
      replace "nrequire(<b args>)" with "__nRequire(<args>)" 
      replace "nrequire_action(<b args>)" with "__nRequire_Action(<args>)" 
      replace "nrequire_action_quiet(<b args>)" with "__nRequire_Action_Quiet(<args>)" 
      replace "nrequire_action_string(<b args>)" with "__nRequire_Action_String(<args>)" 
      replace "nrequire_quiet(<b args>)" with "__nRequire_Quiet(<args>)" 
      replace "nrequire_string(<b args>)" with "__nRequire_String(<args>)" 
      replace "nverify(<b args>)" with "__nVerify(<args>)" 
      replace "nverify_string(<b args>)" with "__nVerify_String(<args>)" 
      replace "require_action_quiet(<b args>)" with "__Require_Action_Quiet(<args>)" 
      replace "require_noerr_action_quiet(<b args>)" with "__Require_noErr_Action_Quiet(<args>)" 
      replace "require_noerr_quiet(<b args>)" with "__Require_noErr_Quiet(<args>)" 
      replace "require_quiet(<b args>)" with "__Require_Quiet(<args>)" 
      replace "check_compile_time(<b args>)" with "__Check_Compile_Time(<args>)" 
      replace "debug_string(<b args>)" with "__Debug_String(<args>)"
 *
 */

参考文章

官方适配iOS11原文
译文

safe area

原文地址:https://www.cnblogs.com/en815/p/7593048.html