我目前正在开发一个带有用户界面的应用程序,就像Twitter for Mac(像iOS一样推进/退出视图)。
有没有人为桌面Cocoa实现了UIViewController?这样可以节省我很多时间。
答案 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)
}
}