【问题标题】:Animating NSTabView Views动画 NSTabView 视图
【发布时间】:2014-11-19 10:19:50
【问题描述】:

我正在尝试在选择视图时使用幻灯片为 NSTabView 的每个视图设置动画。 我有这个工作方式,但它只在我第一次选择新标签视图时动画。之后我在切换选项卡视图时看不到动画,虽然我可以看到每次都触发该函数。?

override func tabView(tabView: NSTabView, didSelectTabViewItem tabViewItem: NSTabViewItem) {
    tabViewItem.view!.setFrameOrigin(NSPoint(x: tabViewItem.view!.frame.origin.x + 300, y: tabViewItem.view!.frame.origin.y))
    tabViewItem.view!.animator().setFrameOrigin(NSPoint(x: tabViewItem.view!.frame.origin.x - 300, y: tabViewItem.view!.frame.origin.y))
    // i can see this fires every time i switch tab views but the animation only works the fist time
}

【问题讨论】:

  • 你解决过这个问题吗?
  • 为什么要标记为 NSTableView?

标签: swift cocoa nstabview


【解决方案1】:

为了解决第一次遇到的问题,我做了一些改动。只需定义一个整数来存储您的委托中以前的选项卡索引。

- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem{

    CABasicAnimation *controlPosAnim = [CABasicAnimation animationWithKeyPath:@"position"];
    if (prevTabViewIndex>[tabView indexOfTabViewItem:tabViewItem]) {
        [controlPosAnim setFromValue:[NSValue valueWithPoint:CGPointMake(tabViewItem.view.frame.origin.x - 500,tabViewItem.view.frame.origin.y)]];

    } else {
        [controlPosAnim setFromValue:[NSValue valueWithPoint:CGPointMake(tabViewItem.view.frame.origin.x + 500,tabViewItem.view.frame.origin.y)]];
    }

    [controlPosAnim setToValue:[NSValue valueWithPoint:CGPointMake(tabViewItem.view.frame.origin.x,tabViewItem.view.frame.origin.y)]];
    [[tabViewItem.view layer] addAnimation:controlPosAnim forKey:@"controlViewPosition"];
    [tabViewItem.view setAnimations:[NSDictionary dictionaryWithObjectsAndKeys:controlPosAnim, @"frameOrigin", nil]];

    [tabViewItem.view.animator setFrameOrigin : CGPointMake(tabViewItem.view.frame.origin.x,tabViewItem.view.frame.origin.y)];

    prevTabViewIndex = [tabView indexOfTabViewItem:tabViewItem];
}

【讨论】:

    【解决方案2】:

    您必须确保 NSTabView 项目是有图层支持的,因此一旦(例如在 windowDidLoad() 中)调用此函数:

    for tabViewItem in self.tabView.tabViewItems {
      if let tabViewItemView = tabViewItem.view {
        tabViewItemView.wantsLayer = true
      }
    }
    

    这是我对 Swift 的 muharrem 答案的更新版本,带有正确的动画偏移:

    private var previousTabViewIndex: Int = 0
    
    public func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) {
      guard let tabViewItem = tabViewItem,
            let tabViewItemView = tabViewItem.view,
            let tabViewItemLayer = tabViewItemView.layer else { return }
    
      let animation = CABasicAnimation(keyPath: #keyPath(CALayer.position))
      let tabViewIndex = tabView.indexOfTabViewItem(tabViewItem)
      let origin = CGPoint(x: tabViewItemView.frame.origin.x, y: tabViewItemView.frame.origin.y)
      var offsetX = self.tabView.frame.width
      if self.previousTabViewIndex > tabViewIndex {
        offsetX *= -1
      }
    
      animation.fromValue = NSValue(point: CGPoint(x: origin.x + offsetX, y: origin.y))
      animation.toValue = NSValue(point: origin)
      tabViewItemLayer.add(animation, forKey: "controlViewPosition")
    
      self.previousTabViewIndex = tabViewIndex
    }
    

    【讨论】:

      【解决方案3】:

      如果您使用的是 NSTabViewController。 只需在 viewDidLoad 方法中设置 transitionOptions 即可。

      class TabVC: NSTabViewController {
      
          override func viewDidLoad() {
              super.viewDidLoad()
              /// When new tab will select, it will perform slide transition.
              self.transitionOptions = .slideRight
          }
          
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-03
        • 1970-01-01
        • 1970-01-01
        • 2014-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多