在UICollectionView中将单元格对齐在中心(水平)

MQ.*_*MQ. 7 center ios uicollectionview swift tvos

我第一次使用UICollectionView不知道如何做到这一点.我正在尝试为tvOS创建一个应用程序,并希望显示像airbnb tvos app这样的菜单.我以某种方式尝试实现该特定格式didUpdateFocusInContext但问题是关于第一次出现,因为第一次出现发生在默认点上,即0,0的集合视图导致混乱.继承了我迄今为止所做的工作.

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
  if let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as? ShowCell {
    menuData = dataArray[indexPath.row] as! NSDictionary
    cell.configureCell(menuData.objectForKey("name") as! String)

    return cell
  }
  else {
    return ShowCell()
  }
}

override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
  if let previousItem = context.previouslyFocusedView as? ShowCell {
    UIView.animateWithDuration(0.2, animations: { () -> Void in
      previousItem.showImg.frame.size = self.originalCellSize
    })
  }
  if let nextItem = context.nextFocusedView as? ShowCell {
    UIView.animateWithDuration(0.2, animations: { () -> Void in
      nextItem.showImg.frame = CGRectMake(
                                    self.view.frame.width/2 - self.focusCellSize.width/2, 
                                    169.0, 
                                    self.focusCellSize.width, 
                                    self.focusCellSize.height)

    })
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我想要实现的视图,我已经实现了它,但是后来的索引意味着1,2之后的索引在此输入图像描述

这是第一次出现时的起始行为,当我将控件移动到它时,它就像这样发生 在此输入图像描述

在此输入图像描述

这就是我真正想要的,但我正在努力将我的专注细胞放到屏幕的中间,同样我的前一个和下一个在两边.我知道我明确给出了帧坐标这是不正确的这只是我正在运行的测试用例而没有其他但我找不到这样做的方法

Wai*_*ain 3

我将分别控制焦点和集合内容偏移(滚动位置)。

对于内容偏移,您应该设置节边距和项间间距,以便一个单元格居中且相邻单元格在边缘可见。您可以在不显示任何焦点的情况下获得此设置并进行测试。

当您滚动(焦点改变)时,大概很难让项目精确地移动到中心。要解决此问题,请实现- scrollViewWillEndDragging:withVelocity:targetContentOffset:在 处查找项目targetContentOffset并获取其中心点(从布局属性)。这样您就可以修改targetContentOffset,使滚动完全以项目居中结束。

现在,焦点应该由单元格本身管理,而不是由集合视图管理。下面是单元格焦点更改动画的(稍大)示例。它使用制图来更改图像视图约束并将变换应用于标签。您可以根据您希望图像和标签如何相互作用来执行类似的操作。

UIImageView请注意,当 a具有焦点并已设置时,下面的代码还应用了类似于苹果提供的库存的运动效果变换adjustsImageWhenAncestorFocused。如果您不希望这样,您可以大大简化和缩短代码。

override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
    super.didUpdateFocusInContext(context, withAnimationCoordinator: coordinator)

    if (context.nextFocusedView == self) {
        UIView.animateWithDuration(0.1,
            animations: { () -> Void in
                self.imageConstraints = constrain(self.itemImageView, replace: self.imageConstraints!) {
                    $0.top == $0.superview!.top
                    $0.bottom == $0.superview!.bottom
                    $0.leading == $0.superview!.leading
                    $0.trailing == $0.superview!.trailing
                }
                self.itemLabel.transform = CGAffineTransformMakeTranslation(0, 60)
                self.itemLabel.layer.backgroundColor = UIColor.darkGrayColor().colorWithAlphaComponent(0).CGColor

                self.layer.shadowOpacity = 1

                self.layoutIfNeeded()
            }, completion: nil)

        let minMaxAngle = 10.0
        let m34 = CGFloat(1.0 / -1250)
        let angle = CGFloat(minMaxAngle * M_PI / 180.0)

        var baseTransform = CATransform3DIdentity
        baseTransform.m34 = m34

        let rotateXmin = CATransform3DRotate(baseTransform, -1 * angle, 1.0, 0.0, 0.0);
        let rotateXmax = CATransform3DRotate(baseTransform, angle, 1.0, 0.0, 0.0);
        let rotateYmin = CATransform3DRotate(baseTransform, angle, 0.0, 1.0, 0.0);
        let rotateYmax = CATransform3DRotate(baseTransform, -1 * angle, 0.0, 1.0, 0.0);

        let verticalMotionEffect = UIInterpolatingMotionEffect(keyPath: "layer.transform",
            type: .TiltAlongVerticalAxis)
        verticalMotionEffect.minimumRelativeValue = NSValue(CATransform3D: rotateXmin)
        verticalMotionEffect.maximumRelativeValue = NSValue(CATransform3D: rotateXmax)

        let horizontalMotionEffect = UIInterpolatingMotionEffect(keyPath: "layer.transform",
            type: .TiltAlongHorizontalAxis)
        horizontalMotionEffect.minimumRelativeValue = NSValue(CATransform3D: rotateYmin)
        horizontalMotionEffect.maximumRelativeValue = NSValue(CATransform3D: rotateYmax)

        let group = UIMotionEffectGroup()
        group.motionEffects = [horizontalMotionEffect, verticalMotionEffect]

        self.addMotionEffect(group)

    }
    else {
        UIView.animateWithDuration(0.3,
            animations: { () -> Void in
                self.imageConstraints = constrain(self.itemImageView, replace: self.imageConstraints!) {
                    $0.top == $0.superview!.top + 20
                    $0.bottom == $0.superview!.bottom - 20
                    $0.leading == $0.superview!.leading + 20
                    $0.trailing == $0.superview!.trailing - 20
                }
                self.itemLabel.transform = CGAffineTransformIdentity
                self.itemLabel.layer.backgroundColor = UIColor.darkGrayColor().colorWithAlphaComponent(0.75).CGColor

                self.layer.shadowOpacity = 0

                self.layoutIfNeeded()
            }, completion: nil)

        for effect in self.motionEffects {
            self.removeMotionEffect(effect)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)