UINavigationController - 类似于Desktop-Cocoa?

时间:2011-01-31 16:19:31

标签: cocoa ios uinavigationcontroller

我目前正在开发一个带有用户界面的应用程序,就像Twitter for Mac(像iOS一样推进/退出视图)。

有没有人为桌面Cocoa实现了UIViewController?这样可以节省我很多时间。

3 个答案:

答案 0 :(得分:4)

此时标准AppKit中没有一个。你必须自己写。

如果您决定走这条道路,这可能会有所帮助:http://parsekit.com/umekit/

UMEKit是Cocoa的一个小框架,它实现了UIKit类和UI组件的一些等价物。

答案 1 :(得分:3)

我花了很多年的时间寻找这个并开始写我自己的,然后找到了https://github.com/bfolder/BFNavigationController

由于某种原因,谷歌不知道它。

答案 2 :(得分:3)

这里我们如何NavigationController,没有导航栏。使用导航项之间的过渡实现导航栏,类似于下面示例中的视图之间的过渡。

import AppKit

public class NavigationController: NSViewController {

   public private (set) var viewControllers: [NSViewController] = []

   open override func loadView() {
      view = NSView()
      view.wantsLayer = true
   }

   public init(rootViewController: NSViewController) {
      super.init(nibName: nil, bundle: nil)
      pushViewController(rootViewController, animated: false)
   }

   public required init?(coder: NSCoder) {
      fatalError()
   }
}

extension NavigationController {

   public var topViewController: NSViewController? {
      return viewControllers.last
   }

   public func pushViewControllerAnimated(_ viewController: NSViewController) {
      pushViewController(viewController, animated: true)
   }

   public func pushViewController(_ viewController: NSViewController, animated: Bool) {
      viewController.navigationController = self
      viewController.view.wantsLayer = true
      if animated, let oldVC = topViewController {
         embedChildViewController(viewController)
         let endFrame = oldVC.view.frame
         let startFrame = endFrame.offsetBy(dx: endFrame.width, dy: 0)
         viewController.view.frame = startFrame
         viewController.view.alphaValue = 0.85
         viewControllers.append(viewController)
         NSAnimationContext.runAnimationGroup({ context in
            context.duration = 0.2
            context.allowsImplicitAnimation = true
            context.timingFunction = .easeOut
            viewController.view.animator().frame = endFrame
            viewController.view.animator().alphaValue = 1
            oldVC.view.animator().alphaValue = 0.25
         }) {
            oldVC.view.alphaValue = 1
            oldVC.view.removeFromSuperview()
         }
      } else {
         embedChildViewController(viewController)
         viewControllers.append(viewController)
      }
   }

   @discardableResult
   public func popViewControllerAnimated() -> NSViewController? {
      return popViewController(animated: true)
   }

   @discardableResult
   public func popViewController(animated: Bool) -> NSViewController? {
      guard let oldVC = viewControllers.popLast() else {
         return nil
      }

      if animated, let newVC = topViewController {
         let endFrame = oldVC.view.frame.offsetBy(dx: oldVC.view.frame.width, dy: 0)
         view.addSubview(newVC.view, positioned: .below, relativeTo: oldVC.view)
         NSAnimationContext.runAnimationGroup({ context in
            context.duration = 0.23
            context.allowsImplicitAnimation = true
            context.timingFunction = .easeIn
            oldVC.view.animator().frame = endFrame
            oldVC.view.animator().alphaValue = 0.85
         }) {
            self.unembedChildViewController(oldVC)
         }
      } else {
         unembedChildViewController(oldVC)
      }
      return oldVC
   }

}

可重复使用的扩展程序:

extension NSViewController {

   private struct OBJCAssociationKey {
      static var navigationController = "com.mc.navigationController"
   }

   public var navigationController: NavigationController? {
      get {
         return ObjCAssociation.value(from: self, forKey: &OBJCAssociationKey.navigationController)
      } set {
         ObjCAssociation.setAssign(value: newValue, to: self, forKey: &OBJCAssociationKey.navigationController)
      }
   }
}

extension NSViewController {

   public func embedChildViewController(_ vc: NSViewController, container: NSView? = nil) {
      addChildViewController(vc)
      vc.view.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
      vc.view.autoresizingMask = [.height, .width]
      (container ?? view).addSubview(vc.view)
   }

   public func unembedChildViewController(_ vc: NSViewController) {
      vc.view.removeFromSuperview()
      vc.removeFromParentViewController()
   }
}

struct ObjCAssociation {

   static func value<T>(from object: AnyObject, forKey key: UnsafeRawPointer) -> T? {
      return objc_getAssociatedObject(object, key) as? T
   }

   static func setAssign<T>(value: T?, to object: Any, forKey key: UnsafeRawPointer) {
      objc_setAssociatedObject(object, key, value, .OBJC_ASSOCIATION_ASSIGN)
   }

   static func setRetainNonAtomic<T>(value: T?, to object: Any, forKey key: UnsafeRawPointer) {
      objc_setAssociatedObject(object, key, value, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
   }

   static func setCopyNonAtomic<T>(value: T?, to object: Any, forKey key: UnsafeRawPointer) {
      objc_setAssociatedObject(object, key, value, .OBJC_ASSOCIATION_COPY_NONATOMIC)
   }

   static func setRetain<T>(value: T?, to object: Any, forKey key: UnsafeRawPointer) {
      objc_setAssociatedObject(object, key, value, .OBJC_ASSOCIATION_RETAIN)
   }

   static func setCopy<T>(value: T?, to object: Any, forKey key: UnsafeRawPointer) {
      objc_setAssociatedObject(object, key, value, .OBJC_ASSOCIATION_COPY)
   }
}