【问题标题】:UINavigationController-Alike for Desktop-Cocoa?UINavigationController-Alike for Desktop-Cocoa?
【发布时间】:2011-01-31 16:19:30
【问题描述】:

我目前正在开发一个用户界面类似于 Mac 版 Twitter 的应用程序(像在 iOS 上一样推入/退出视图)。

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

【问题讨论】:

    标签: cocoa ios uinavigationcontroller


    【解决方案1】:

    目前标准 AppKit 中还没有。你必须自己写。

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

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

    【讨论】:

    • 对于那些多年来仍在照料的人来说,这个项目似乎已经死了。试试下面的 BFNavigationController 答案,它仍然在 Xcode 10 上构建干净
    • 我们是否也有导航返回的东西.. 就像 mac appstore 中的 UI?
    【解决方案2】:

    这里是我们如何做到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)
       }
    }
    

    【讨论】:

    • 暂时有效。谢谢。
    • @Fabian:如果您有任何工作示例,可以发帖。
    • @Vlad:如果您有意见,请分享
    • @EXC_BAD_ACCESS 我无法再访问该代码,抱歉。祝你好运!
    【解决方案3】:

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

    由于某种原因,Google 不知道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-01
      • 2022-01-09
      • 2019-07-22
      • 1970-01-01
      • 1970-01-01
      • 2022-12-04
      • 1970-01-01
      • 2010-09-22
      相关资源
      最近更新 更多