Merged PR 221593: Swift 4.2 and resolving public extension conflicts

- Updating to Swift 4.2
- Resolving naming conflicts with public extensions to Foundation / UIKit classes

For the name resolution, I resolved the minimum set necessary for this pod to compile in Outlook iOS. If possible, extensions were marked explicitly with `internal`. Where not possible (eg `@objc` methods), methods were prefixed with `ms_`.

Related work items: #675596
This commit is contained in:
Chase Holland 2019-01-16 20:09:49 +00:00
Родитель e3e3dcec00
Коммит 12dcd14dbb
34 изменённых файлов: 82 добавлений и 101 удалений

Просмотреть файл

@ -8,7 +8,7 @@ Pod::Spec.new do |s|
s.platform = :ios s.platform = :ios
s.ios.deployment_target = "10.0" s.ios.deployment_target = "10.0"
s.swift_version = "4.1" s.swift_version = "4.2"
s.source = { :git => "https://onedrive.visualstudio.com/Design/The%20Studio/_git/fabric-ios", :tag => "#{s.version}" } s.source = { :git => "https://onedrive.visualstudio.com/Design/The%20Studio/_git/fabric-ios", :tag => "#{s.version}" }
s.source_files = "OfficeUIFabric/**/*.{swift,h}" s.source_files = "OfficeUIFabric/**/*.{swift,h}"

Просмотреть файл

@ -559,10 +559,11 @@
TargetAttributes = { TargetAttributes = {
A5CEC15020D980B20016922A = { A5CEC15020D980B20016922A = {
CreatedOnToolsVersion = 9.4.1; CreatedOnToolsVersion = 9.4.1;
LastSwiftMigration = 0940; LastSwiftMigration = 1010;
}; };
A5CEC15920D980B30016922A = { A5CEC15920D980B30016922A = {
CreatedOnToolsVersion = 9.4.1; CreatedOnToolsVersion = 9.4.1;
LastSwiftMigration = 1010;
}; };
}; };
}; };
@ -820,7 +821,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.OfficeUIFabric; PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.OfficeUIFabric;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_VERSION = 4.0; SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Dogfood; name = Dogfood;
@ -839,7 +840,7 @@
); );
PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.OfficeUIFabricTests; PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.OfficeUIFabricTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0; SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Dogfood; name = Dogfood;
@ -986,7 +987,7 @@
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0; SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Debug; name = Debug;
@ -1012,7 +1013,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.OfficeUIFabric; PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.OfficeUIFabric;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_VERSION = 4.0; SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Release; name = Release;
@ -1031,7 +1032,7 @@
); );
PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.OfficeUIFabricTests; PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.OfficeUIFabricTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0; SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Debug; name = Debug;
@ -1050,7 +1051,7 @@
); );
PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.OfficeUIFabricTests; PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.OfficeUIFabricTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0; SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Release; name = Release;

Просмотреть файл

@ -183,7 +183,7 @@ open class MSBadgeField: UIView {
textField.addTarget(self, action: #selector(handleTextFieldTextChanged), for: .editingChanged) textField.addTarget(self, action: #selector(handleTextFieldTextChanged), for: .editingChanged)
textField.addObserver(self, forKeyPath: #keyPath(UITextField.selectedTextRange), options: .new, context: nil) textField.addObserver(self, forKeyPath: #keyPath(UITextField.selectedTextRange), options: .new, context: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleOrientationChanged), name: .UIDeviceOrientationDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(handleOrientationChanged), name: UIDevice.orientationDidChangeNotification, object: nil)
// An accessible container must set isAccessibilityElement to false // An accessible container must set isAccessibilityElement to false
isAccessibilityElement = false isAccessibilityElement = false
@ -231,7 +231,7 @@ open class MSBadgeField: UIView {
private func setupDraggingWindow() { private func setupDraggingWindow() {
// The dragging window must be on top of any other window (keyboard, status bar etc.) // The dragging window must be on top of any other window (keyboard, status bar etc.)
draggingWindow.windowLevel = CGFloat.greatestFiniteMagnitude draggingWindow.windowLevel = UIWindow.Level(rawValue: .greatestFiniteMagnitude)
draggingWindow.backgroundColor = .clear draggingWindow.backgroundColor = .clear
draggingWindow.isHidden = true draggingWindow.isHidden = true
} }
@ -285,7 +285,7 @@ open class MSBadgeField: UIView {
} }
open override var intrinsicContentSize: CGSize { open override var intrinsicContentSize: CGSize {
return CGSize(width: UIViewNoIntrinsicMetric, height: contentHeight(forBoundingWidth: width)) return CGSize(width: UIView.noIntrinsicMetric, height: contentHeight(forBoundingWidth: width))
} }
private func updateConstrainedBadges() { private func updateConstrainedBadges() {
@ -830,14 +830,14 @@ open class MSBadgeField: UIView {
@objc public func voiceOverFocusOnTextFieldAndAnnounce(_ announcement: String?) { @objc public func voiceOverFocusOnTextFieldAndAnnounce(_ announcement: String?) {
guard let announcement = announcement, !announcement.isEmpty else { guard let announcement = announcement, !announcement.isEmpty else {
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, textField) UIAccessibility.post(notification: .screenChanged, argument: textField)
return return
} }
let previousAccessibilityLabel = textField.accessibilityLabel let previousAccessibilityLabel = textField.accessibilityLabel
// Update the accessibilityLabel to include the desired announcement // Update the accessibilityLabel to include the desired announcement
textField.accessibilityLabel = "\(announcement). \(previousAccessibilityLabel ?? "")" textField.accessibilityLabel = "\(announcement). \(previousAccessibilityLabel ?? "")"
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, textField) UIAccessibility.post(notification: .screenChanged, argument: textField)
// Reset the accessibility to the proper label // Reset the accessibility to the proper label
// Allow the label to get reset on a delay so the notification has time to fire before it changes // Allow the label to get reset on a delay so the notification has time to fire before it changes
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { [weak self] in

Просмотреть файл

@ -204,7 +204,7 @@ open class MSBadgeView: UIView {
isUserInteractionEnabled = true isUserInteractionEnabled = true
isAccessibilityElement = true isAccessibilityElement = true
accessibilityTraits = UIAccessibilityTraitButton accessibilityTraits = .button
updateAccessibility() updateAccessibility()
} }

Просмотреть файл

@ -133,7 +133,7 @@ class MSCalendarView: UIView {
override var accessibilityHint: String? { get { return "Accessibility.Calendar.Hint".localized } set { } } override var accessibilityHint: String? { get { return "Accessibility.Calendar.Hint".localized } set { } }
override var accessibilityTraits: UIAccessibilityTraits { get { return UIAccessibilityTraitAdjustable | super.accessibilityTraits } set { } } override var accessibilityTraits: UIAccessibilityTraits { get { return super.accessibilityTraits.union(.adjustable) } set { } }
override var accessibilityValue: String? { override var accessibilityValue: String? {
get { return accessibleViewDelegate?.accessibilityValueForAccessibleView?(self) ?? super.accessibilityValue } get { return accessibleViewDelegate?.accessibilityValueForAccessibleView?(self) ?? super.accessibilityValue }

Просмотреть файл

@ -311,7 +311,7 @@ private class MSSelectionOverlayView: UIView {
addSubview(view) addSubview(view)
} }
bringSubview(toFront: view) bringSubviewToFront(view)
view.isHidden = !(selected || highlighted) view.isHidden = !(selected || highlighted)
} }
} }

Просмотреть файл

@ -91,7 +91,7 @@ open class MSActivityIndicatorView: UIView {
let shapeLayer = CAShapeLayer() let shapeLayer = CAShapeLayer()
shapeLayer.contentsScale = UIScreen.main.scale shapeLayer.contentsScale = UIScreen.main.scale
shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineJoin = kCALineJoinBevel shapeLayer.lineJoin = .bevel
return shapeLayer return shapeLayer
}() }()
private let loaderRotationAnimation: CABasicAnimation = { private let loaderRotationAnimation: CABasicAnimation = {
@ -101,11 +101,11 @@ open class MSActivityIndicatorView: UIView {
loaderRotationAnimation.toValue = NSNumber(value: 2 * Double.pi) loaderRotationAnimation.toValue = NSNumber(value: 2 * Double.pi)
loaderRotationAnimation.duration = Constants.rotationAnimationDuration loaderRotationAnimation.duration = Constants.rotationAnimationDuration
loaderRotationAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) loaderRotationAnimation.timingFunction = CAMediaTimingFunction(name: .linear)
loaderRotationAnimation.isRemovedOnCompletion = false loaderRotationAnimation.isRemovedOnCompletion = false
loaderRotationAnimation.repeatCount = Float.infinity loaderRotationAnimation.repeatCount = .infinity
loaderRotationAnimation.fillMode = kCAFillModeForwards loaderRotationAnimation.fillMode = .forwards
loaderRotationAnimation.autoreverses = false loaderRotationAnimation.autoreverses = false
return loaderRotationAnimation return loaderRotationAnimation
@ -185,7 +185,7 @@ open class MSActivityIndicatorView: UIView {
loaderLayer.frame = CGRect(x: 0.0, y: 0.0, width: sideSize, height: sideSize) loaderLayer.frame = CGRect(x: 0.0, y: 0.0, width: sideSize, height: sideSize)
loaderLayer.strokeColor = color.cgColor loaderLayer.strokeColor = color.cgColor
loaderLayer.lineWidth = strokeThickness loaderLayer.lineWidth = strokeThickness
loaderLayer.lineCap = kCALineCapRound loaderLayer.lineCap = .round
loaderLayer.path = loaderPath.cgPath loaderLayer.path = loaderPath.cgPath
setNeedsLayout() setNeedsLayout()

Просмотреть файл

@ -16,7 +16,7 @@ open class MSBlurringView: UIView {
private let blurVisualEffectView: UIVisualEffectView private let blurVisualEffectView: UIVisualEffectView
private let backgroundView: UIView private let backgroundView: UIView
public init(style: UIBlurEffectStyle, backgroundColor: UIColor = Constants.defaultBackgroundColor, backgroundAlpha: CGFloat = Constants.defaultBackgroundAlpha) { public init(style: UIBlurEffect.Style, backgroundColor: UIColor = Constants.defaultBackgroundColor, backgroundAlpha: CGFloat = Constants.defaultBackgroundAlpha) {
blurEffect = UIBlurEffect(style: style) blurEffect = UIBlurEffect(style: style)
blurVisualEffectView = UIVisualEffectView(effect: blurEffect) blurVisualEffectView = UIVisualEffectView(effect: blurEffect)

Просмотреть файл

@ -33,7 +33,7 @@ open class MSResizingHandleView: UIView {
} }
open override var intrinsicContentSize: CGSize { open override var intrinsicContentSize: CGSize {
return CGSize(width: UIViewNoIntrinsicMetric, height: MSResizingHandleView.height) return CGSize(width: UIView.noIntrinsicMetric, height: MSResizingHandleView.height)
} }
open override func sizeThatFits(_ size: CGSize) -> CGSize { open override func sizeThatFits(_ size: CGSize) -> CGSize {

Просмотреть файл

@ -52,9 +52,9 @@ open class MSSeparator: UIView {
open override var intrinsicContentSize: CGSize { open override var intrinsicContentSize: CGSize {
switch orientation { switch orientation {
case .horizontal: case .horizontal:
return CGSize(width: UIViewNoIntrinsicMetric, height: height) return CGSize(width: UIView.noIntrinsicMetric, height: height)
case .vertical: case .vertical:
return CGSize(width: width, height: UIViewNoIntrinsicMetric) return CGSize(width: width, height: UIView.noIntrinsicMetric)
} }
} }

Просмотреть файл

@ -76,7 +76,7 @@ open class MSTwoLinesTitleView: UIView {
titleButton.accessibilityHint = titleAccessibilityHint titleButton.accessibilityHint = titleAccessibilityHint
} }
} }
open var titleAccessibilityTrait: UIAccessibilityTraits = UIAccessibilityTraitStaticText | UIAccessibilityTraitHeader { open var titleAccessibilityTrait: UIAccessibilityTraits = [.staticText, .header] {
didSet { didSet {
titleButton.accessibilityTraits = titleAccessibilityTrait titleButton.accessibilityTraits = titleAccessibilityTrait
} }
@ -87,7 +87,7 @@ open class MSTwoLinesTitleView: UIView {
subtitleButton.accessibilityHint = subtitleAccessibilityHint subtitleButton.accessibilityHint = subtitleAccessibilityHint
} }
} }
open var subtitleAccessibilityTrait: UIAccessibilityTraits = UIAccessibilityTraitStaticText | UIAccessibilityTraitHeader { open var subtitleAccessibilityTrait: UIAccessibilityTraits = [.staticText, .header] {
didSet { didSet {
subtitleButton.accessibilityTraits = subtitleAccessibilityTrait subtitleButton.accessibilityTraits = subtitleAccessibilityTrait
} }

Просмотреть файл

@ -21,7 +21,7 @@ class MSAccessibilityContainerView: UIView {
override var isAccessibilityElement: Bool { get { return true } set { } } override var isAccessibilityElement: Bool { get { return true } set { } }
override var accessibilityTraits: UIAccessibilityTraits { get { return UIAccessibilityTraitAdjustable } set { } } override var accessibilityTraits: UIAccessibilityTraits { get { return .adjustable } set { } }
override var accessibilityLabel: String? { get { return delegate?.accessibilityLabelForAccessibleView?(self) } set { } } override var accessibilityLabel: String? { get { return delegate?.accessibilityLabelForAccessibleView?(self) } set { } }

Просмотреть файл

@ -286,7 +286,7 @@ extension MSDatePickerController: UICollectionViewDelegate {
let cell = collectionView.cellForItem(at: indexPath) as? MSCalendarViewDayCell { let cell = collectionView.cellForItem(at: indexPath) as? MSCalendarViewDayCell {
cell.setSelectionType(selectionType) cell.setSelectionType(selectionType)
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: UICollectionViewScrollPosition()) collectionView.selectItem(at: indexPath, animated: false, scrollPosition: UICollectionView.ScrollPosition())
} else { } else {
collectionView.deselectItem(at: indexPath, animated: false) collectionView.deselectItem(at: indexPath, animated: false)
} }

Просмотреть файл

@ -30,7 +30,7 @@ class MSDateTimePickerViewComponentCell: UITableViewCell {
} }
} }
override init(style: UITableViewCellStyle, reuseIdentifier: String?) { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: reuseIdentifier) super.init(style: .default, reuseIdentifier: reuseIdentifier)
textLabel?.textAlignment = .center textLabel?.textAlignment = .center

Просмотреть файл

@ -50,7 +50,7 @@ public class MSDateTimePicker: NSObject {
/// - date: The initial date selected on the presented pickers /// - date: The initial date selected on the presented pickers
@objc public func present(from presentingController: UIViewController, with mode: MSDateTimePickerMode, for date: Date = Date()) { @objc public func present(from presentingController: UIViewController, with mode: MSDateTimePickerMode, for date: Date = Date()) {
self.presentingController = presentingController self.presentingController = presentingController
if UIAccessibilityIsVoiceOverRunning() { if UIAccessibility.isVoiceOverRunning {
presentDateTimePickerForAccessibility(initialDate: date, showsTime: mode == .dateTime) presentDateTimePickerForAccessibility(initialDate: date, showsTime: mode == .dateTime)
return return
} }

Просмотреть файл

@ -43,7 +43,7 @@ class MSDrawerPresentationController: UIPresentationController {
view.isAccessibilityElement = true view.isAccessibilityElement = true
view.accessibilityLabel = "Accessibility.Dismiss.Label".localized view.accessibilityLabel = "Accessibility.Dismiss.Label".localized
view.accessibilityHint = "Accessibility.Dismiss.Hint".localized view.accessibilityHint = "Accessibility.Dismiss.Hint".localized
view.accessibilityTraits = UIAccessibilityTraitButton view.accessibilityTraits = .button
return view return view
}() }()
private lazy var dimmingView: MSDimmingView = { private lazy var dimmingView: MSDimmingView = {
@ -92,8 +92,8 @@ class MSDrawerPresentationController: UIPresentationController {
override func presentationTransitionDidEnd(_ completed: Bool) { override func presentationTransitionDidEnd(_ completed: Bool) {
if completed { if completed {
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, contentView) UIAccessibility.post(notification: .screenChanged, argument: contentView)
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, "Accessibility.Alert".localized) UIAccessibility.post(notification: .announcement, argument: "Accessibility.Alert".localized)
} else { } else {
accessibilityContainer.removeFromSuperview() accessibilityContainer.removeFromSuperview()
separator.removeFromSuperview() separator.removeFromSuperview()
@ -118,7 +118,7 @@ class MSDrawerPresentationController: UIPresentationController {
accessibilityContainer.removeFromSuperview() accessibilityContainer.removeFromSuperview()
separator.removeFromSuperview() separator.removeFromSuperview()
removePresentedViewMask() removePresentedViewMask()
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, sourceObject) UIAccessibility.post(notification: .screenChanged, argument: sourceObject)
} }
} }
@ -150,7 +150,7 @@ class MSDrawerPresentationController: UIPresentationController {
override func containerViewWillLayoutSubviews() { override func containerViewWillLayoutSubviews() {
super.containerViewWillLayoutSubviews() super.containerViewWillLayoutSubviews()
// In non-animated presentations presented view will be force-placed into containerView by UIKit after separator thus hiding it // In non-animated presentations presented view will be force-placed into containerView by UIKit after separator thus hiding it
containerView?.bringSubview(toFront: separator) containerView?.bringSubviewToFront(separator)
} }
override func containerViewDidLayoutSubviews() { override func containerViewDidLayoutSubviews() {
@ -197,7 +197,7 @@ class MSDrawerPresentationController: UIPresentationController {
case .up: case .up:
margins.bottom = bounds.height - actualPresentationOrigin margins.bottom = bounds.height - actualPresentationOrigin
} }
return UIEdgeInsetsInsetRect(bounds, margins) return bounds.inset(by: margins)
} }
private func frameForContentView() -> CGRect { private func frameForContentView() -> CGRect {
@ -219,7 +219,7 @@ class MSDrawerPresentationController: UIPresentationController {
case .up: case .up:
contentMargins.top = max(minVerticalMargin, containerView.safeAreaInsetsIfAvailable.top + minBackgroundHeight) contentMargins.top = max(minVerticalMargin, containerView.safeAreaInsetsIfAvailable.top + minBackgroundHeight)
} }
var contentFrame = UIEdgeInsetsInsetRect(bounds, contentMargins) var contentFrame = bounds.inset(by: contentMargins)
var contentSize = presentedViewController.preferredContentSize var contentSize = presentedViewController.preferredContentSize
switch presentationDirection { switch presentationDirection {
@ -287,7 +287,7 @@ class MSDrawerPresentationController: UIPresentationController {
animation.fromValue = oldMaskPath animation.fromValue = oldMaskPath
animation.duration = duration animation.duration = duration
// To match default timing function used in UIView.animate // To match default timing function used in UIView.animate
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
presentedViewMask.add(animation, forKey: animation.keyPath) presentedViewMask.add(animation, forKey: animation.keyPath)
} }

Просмотреть файл

@ -4,7 +4,7 @@
import Foundation import Foundation
public extension CGSize { extension CGSize {
static var max: CGSize { static var max: CGSize {
return CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude) return CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
} }

Просмотреть файл

@ -4,7 +4,7 @@
import Foundation import Foundation
public extension Calendar { extension Calendar {
private static let sharedAutoUpdatingCalendar: Calendar = .autoupdatingCurrent private static let sharedAutoUpdatingCalendar: Calendar = .autoupdatingCurrent
private static var sharedTimeZoneCalendars = [Calendar]() private static var sharedTimeZoneCalendars = [Calendar]()

Просмотреть файл

@ -6,7 +6,7 @@ import Foundation
// MARK: Calculations // MARK: Calculations
public extension Date { extension Date {
private static var _has24HourFormat: Bool? private static var _has24HourFormat: Bool?
static func has24HourFormat() -> Bool { static func has24HourFormat() -> Bool {
@ -76,7 +76,7 @@ public extension Date {
// MARK: - Components // MARK: - Components
public extension Date { extension Date {
/// The `year` date component of `self`. The time zone used is equal to the `Calendar.current.timeZone`. /// The `year` date component of `self`. The time zone used is equal to the `Calendar.current.timeZone`.
var year: Int { var year: Int {
return Calendar.current.component(.year, from: self) return Calendar.current.component(.year, from: self)

Просмотреть файл

@ -2,7 +2,7 @@
// Copyright © 2018 Microsoft Corporation. All rights reserved. // Copyright © 2018 Microsoft Corporation. All rights reserved.
// //
public extension String { extension String {
var initials: String { var initials: String {
var initials = "" var initials = ""

Просмотреть файл

@ -12,7 +12,7 @@ public extension UIImage {
return nil return nil
} }
if UIAccessibilityDarkerSystemColorsEnabled(), if UIAccessibility.isDarkerSystemColorsEnabled,
let primaryColor = darkerPrimaryColor ?? self.darkerPrimaryColor(forImageNamed: name, in: bundle) { let primaryColor = darkerPrimaryColor ?? self.darkerPrimaryColor(forImageNamed: name, in: bundle) {
// Recolor image with high contrast version of `primaryColor` // Recolor image with high contrast version of `primaryColor`
image = recolorImage(image, withPrimaryColor: primaryColor) image = recolorImage(image, withPrimaryColor: primaryColor)
@ -45,7 +45,7 @@ public extension UIImage {
return image return image
} }
@objc func image(withPrimaryColor primaryColor: UIColor) -> UIImage { internal func image(withPrimaryColor primaryColor: UIColor) -> UIImage {
// Force image to be `AlwaysOriginal` regardless of the setting in `.xcassets` to prevent recoloring caused by `tintColor` // Force image to be `AlwaysOriginal` regardless of the setting in `.xcassets` to prevent recoloring caused by `tintColor`
return UIImage.recolorImage(self, withPrimaryColor: primaryColor).withRenderingMode(.alwaysOriginal) return UIImage.recolorImage(self, withPrimaryColor: primaryColor).withRenderingMode(.alwaysOriginal)
} }

Просмотреть файл

@ -56,7 +56,7 @@ public extension UIView {
} }
} else { } else {
translatesAutoresizingMaskIntoConstraints = true translatesAutoresizingMaskIntoConstraints = true
frame = UIEdgeInsetsInsetRect(superview.bounds, margins) frame = superview.bounds.inset(by: margins)
autoresizingMask = [.flexibleWidth, .flexibleHeight] autoresizingMask = [.flexibleWidth, .flexibleHeight]
} }
} }

Просмотреть файл

@ -4,40 +4,20 @@
import Foundation import Foundation
// MARK: Traits // MARK: Add/Remove Child View Controller
public extension UIViewController {
@objc var isWidthCompact: Bool {
return traitCollection.horizontalSizeClass == .compact
}
@objc var isWidthRegular: Bool {
return traitCollection.horizontalSizeClass == .regular
}
@objc var isHeightCompact: Bool {
return traitCollection.verticalSizeClass == .compact
}
@objc var isHeightRegular: Bool {
return traitCollection.verticalSizeClass == .regular
}
}
// MARK: - Add/Remove Child View Controller
public extension UIViewController { public extension UIViewController {
/// Convenience method that adds a child view controller to the receiver and also establish the parent-children relationship between their corresponding views /// Convenience method that adds a child view controller to the receiver and also establish the parent-children relationship between their corresponding views
@objc func addChildController(_ childController: UIViewController) { @objc func addChildController(_ childController: UIViewController) {
addChildViewController(childController) addChild(childController)
view.addSubview(childController.view) view.addSubview(childController.view)
childController.didMove(toParentViewController: self) childController.didMove(toParent: self)
} }
/// Convenience method that removes a child view controller from the receiver and also remove the parent-children relationship of the childViewController /// Convenience method that removes a child view controller from the receiver and also remove the parent-children relationship of the childViewController
@objc func removeChildController(_ childController: UIViewController) { @objc func removeChildController(_ childController: UIViewController) {
childController.willMove(toParentViewController: nil) childController.willMove(toParent: nil)
childController.view.removeFromSuperview() childController.view.removeFromSuperview()
childController.removeFromParentViewController() childController.removeFromParent()
} }
} }

Просмотреть файл

@ -74,11 +74,11 @@ public class MSHUD: NSObject {
// Orientation // Orientation
// `UIWindow` propagates rotation handling (eg. call to `layoutSubviews`) only to the subviews at the index 0. Because we add the MSHUD container as a sibling of such a view, we must handle rotation events ourselves. // `UIWindow` propagates rotation handling (eg. call to `layoutSubviews`) only to the subviews at the index 0. Because we add the MSHUD container as a sibling of such a view, we must handle rotation events ourselves.
NotificationCenter.default.addObserver(self, selector: #selector(handleOrientationDidChange(_:)), name: .UIApplicationDidChangeStatusBarOrientation, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(handleOrientationDidChange(_:)), name: UIApplication.didChangeStatusBarOrientationNotification, object: nil)
// Keyboard observation // Keyboard observation
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShow(_:)), name: .UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillHide(_:)), name: .UIKeyboardWillHide, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
} }
@objc public func show(in view: UIView, with params: MSHUDParams) { @objc public func show(in view: UIView, with params: MSHUDParams) {
@ -103,7 +103,7 @@ public class MSHUD: NSObject {
presentedHUDView.alpha = 1.0 presentedHUDView.alpha = 1.0
presentedHUDView.transform = .identity presentedHUDView.transform = .identity
}, completion: { _ in }, completion: { _ in
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil) UIAccessibility.post(notification: .screenChanged, argument: nil)
}) })
// Dismiss after delay if needed // Dismiss after delay if needed
@ -157,7 +157,7 @@ public class MSHUD: NSObject {
return return
} }
self.resetIfNeeded() self.resetIfNeeded()
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, presentedHUDView.accessibilityMessageForHide) UIAccessibility.post(notification: .screenChanged, argument: presentedHUDView.accessibilityMessageForHide)
} }
if animated { if animated {
@ -200,8 +200,8 @@ public class MSHUD: NSObject {
@objc private func handleKeyboardWillShow(_ notification: Notification) { @objc private func handleKeyboardWillShow(_ notification: Notification) {
guard let userInfo = notification.userInfo, guard let userInfo = notification.userInfo,
let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue, let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
let keyboardAnimationDuration = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue else { let keyboardAnimationDuration = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue else {
// Invalid keyboard notification // Invalid keyboard notification
return return
} }
@ -213,7 +213,7 @@ public class MSHUD: NSObject {
@objc private func handleKeyboardWillHide(_ notification: Notification) { @objc private func handleKeyboardWillHide(_ notification: Notification) {
guard let userInfo = notification.userInfo, guard let userInfo = notification.userInfo,
let keyboardAnimationDuration = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue else { let keyboardAnimationDuration = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue else {
// Invalid keyboard notification // Invalid keyboard notification
return return
} }

Просмотреть файл

@ -130,7 +130,7 @@ class MSHUDView: UIView {
} }
open override var accessibilityTraits: UIAccessibilityTraits { open override var accessibilityTraits: UIAccessibilityTraits {
get { return super.accessibilityTraits | UIAccessibilityTraitStaticText } get { return super.accessibilityTraits.union(.staticText) }
set { } set { }
} }
} }

Просмотреть файл

@ -225,5 +225,5 @@ open class MSAvatarView: UIView {
open override var isAccessibilityElement: Bool { get { return true } set { } } open override var isAccessibilityElement: Bool { get { return true } set { } }
open override var accessibilityLabel: String? { get { return name ?? email } set { } } open override var accessibilityLabel: String? { get { return name ?? email } set { } }
open override var accessibilityTraits: UIAccessibilityTraits { get { return UIAccessibilityTraitImage } set { } } open override var accessibilityTraits: UIAccessibilityTraits { get { return .image } set { } }
} }

Просмотреть файл

@ -36,7 +36,7 @@ open class MSPersonaCell: UITableViewCell {
return label return label
}() }()
@objc public override init(style: UITableViewCellStyle, reuseIdentifier: String?) { @objc public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: reuseIdentifier) super.init(style: .default, reuseIdentifier: reuseIdentifier)
contentView.addSubview(avatarView) contentView.addSubview(avatarView)

Просмотреть файл

@ -62,7 +62,7 @@ open class MSPersonaListView: UITableView {
} }
} }
@objc override init(frame: CGRect, style: UITableViewStyle) { @objc override init(frame: CGRect, style: UITableView.Style) {
super.init(frame: frame, style: style) super.init(frame: frame, style: style)
backgroundColor = MSColors.background backgroundColor = MSColors.background
@ -170,7 +170,7 @@ extension MSPersonaListView: UITableViewDataSource {
let cell = dequeueReusableCell(withIdentifier: MSPersonaCell.identifier, for: indexPath) as! MSPersonaCell let cell = dequeueReusableCell(withIdentifier: MSPersonaCell.identifier, for: indexPath) as! MSPersonaCell
let persona = personaList[indexPath.row] let persona = personaList[indexPath.row]
cell.setup(persona: persona) cell.setup(persona: persona)
cell.accessibilityTraits = UIAccessibilityTraitButton cell.accessibilityTraits = .button
return cell return cell
case .searchDirectory: case .searchDirectory:
switch searchDirectoryState { switch searchDirectoryState {
@ -187,7 +187,7 @@ extension MSPersonaListView: UITableViewDataSource {
let cell = dequeueReusableCell(withIdentifier: MSActionsCell.identifier, for: indexPath) as! MSActionsCell let cell = dequeueReusableCell(withIdentifier: MSActionsCell.identifier, for: indexPath) as! MSActionsCell
cell.setup(action1Title: "MSPersonaListView.SearchDirectory".localized) cell.setup(action1Title: "MSPersonaListView.SearchDirectory".localized)
cell.action1Button.addTarget(self, action: #selector(searchDirectoryButtonTapped), for: .touchUpInside) cell.action1Button.addTarget(self, action: #selector(searchDirectoryButtonTapped), for: .touchUpInside)
cell.accessibilityTraits = UIAccessibilityTraitButton cell.accessibilityTraits = .button
cell.hideSeparator() cell.hideSeparator()
return cell return cell
} }

Просмотреть файл

@ -89,7 +89,7 @@ class MSPopupMenuItemCell: UITableViewCell {
private let separator = MSSeparator() private let separator = MSSeparator()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) super.init(style: style, reuseIdentifier: reuseIdentifier)
backgroundColor = .clear backgroundColor = .clear
@ -223,17 +223,17 @@ class MSPopupMenuItemCell: UITableViewCell {
private func updateAccessibilityTraits() { private func updateAccessibilityTraits() {
if item?.isEnabled == false { if item?.isEnabled == false {
accessibilityTraits |= UIAccessibilityTraitNotEnabled accessibilityTraits.insert(.notEnabled)
} else { } else {
accessibilityTraits &= ~UIAccessibilityTraitNotEnabled accessibilityTraits.remove(.notEnabled)
} }
if isHeader { if isHeader {
accessibilityTraits &= ~UIAccessibilityTraitButton accessibilityTraits.remove(.button)
accessibilityTraits |= UIAccessibilityTraitHeader accessibilityTraits.insert(.header)
} else { } else {
accessibilityTraits |= UIAccessibilityTraitButton accessibilityTraits.insert(.button)
accessibilityTraits &= ~UIAccessibilityTraitHeader accessibilityTraits.remove(.header)
} }
} }

Просмотреть файл

@ -35,7 +35,7 @@ class MSCardPresentationController: UIPresentationController {
override func presentationTransitionDidEnd(_ completed: Bool) { override func presentationTransitionDidEnd(_ completed: Bool) {
if completed { if completed {
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, presentedViewController.view) UIAccessibility.post(notification: .screenChanged, argument: presentedViewController.view)
} else { } else {
backgroundObscurable.view.removeFromSuperview() backgroundObscurable.view.removeFromSuperview()
} }
@ -52,7 +52,7 @@ class MSCardPresentationController: UIPresentationController {
override func dismissalTransitionDidEnd(_ completed: Bool) { override func dismissalTransitionDidEnd(_ completed: Bool) {
if completed { if completed {
backgroundObscurable.view.removeFromSuperview() backgroundObscurable.view.removeFromSuperview()
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, presentingViewController.view) UIAccessibility.post(notification: .screenChanged, argument: presentingViewController.view)
} }
} }

Просмотреть файл

@ -49,7 +49,7 @@ open class MSPageCardPresenterController: UIViewController {
view.isAccessibilityElement = true view.isAccessibilityElement = true
view.accessibilityLabel = "Accessibility.Dismiss.Label".localized view.accessibilityLabel = "Accessibility.Dismiss.Label".localized
view.accessibilityHint = "Accessibility.Dismiss.Hint".localized view.accessibilityHint = "Accessibility.Dismiss.Hint".localized
view.accessibilityTraits = UIAccessibilityTraitButton view.accessibilityTraits = .button
return view return view
}() }()
@ -87,10 +87,10 @@ open class MSPageCardPresenterController: UIViewController {
view.addSubview(pageControl) view.addSubview(pageControl)
for viewController in viewControllers { for viewController in viewControllers {
addChildViewController(viewController) addChild(viewController)
scrollView.addSubview(viewController.view) scrollView.addSubview(viewController.view)
styleCardView(viewController.view) styleCardView(viewController.view)
viewController.didMove(toParentViewController: self) viewController.didMove(toParent: self)
} }
updateViewAccessibilityElements() updateViewAccessibilityElements()

Просмотреть файл

@ -25,7 +25,7 @@ open class MSActionsCell: UITableViewCell {
private let separator = MSSeparator(style: .default, orientation: .vertical) private let separator = MSSeparator(style: .default, orientation: .vertical)
override init(style: UITableViewCellStyle, reuseIdentifier: String?) { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(action1Button) contentView.addSubview(action1Button)

Просмотреть файл

@ -16,7 +16,7 @@ open class MSActivityIndicatorCell: UITableViewCell {
return activityIndicatorView return activityIndicatorView
}() }()
public override init(style: UITableViewCellStyle, reuseIdentifier: String?) { public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(activityIndicatorView) contentView.addSubview(activityIndicatorView)
} }

Просмотреть файл

@ -24,7 +24,7 @@ open class MSCenteredLabelCell: UITableViewCell {
return label return label
}() }()
public override init(style: UITableViewCellStyle, reuseIdentifier: String?) { public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(label) contentView.addSubview(label)
} }