tvOS 上的 UIControl 会产生哪些事件?

What events are produced by UIControl on tvOS?

对于 UIButton,当按钮获得焦点并且用户点击遥控器时,tvOS 会生成 UIControlEvents.PrimaryActionTriggered(而不是 .TouchUpInside,就像在 iOS 上那样)。

但是,

UIControl 似乎不会产生 这些事件。我看不到它会产生任何事件,事实上,当用户专注于控件并点击遥控器时。

如何使用 tvOS 的自定义 UIControl

A UIControl 不会自行发出任何控制事件。您的子类负责发出事件(通常通过发送自身 sendActionsForControlEvents:)。

由于 UIControl 目前没有针对 tvOS 的文档,可能是因为 Apple 不希望您对其进行子类化。

无论如何,我只玩了一点,但显然要实现您自己的 UIControl 子类,您必须将 canBecomeFocused 重写为 return YES ,并且您必须重写 pressesEnded:withEvent: 以对用户的按下操作(大概是通过发送您自己 sendActionsForControlEvents:.)。

您可能还想覆盖 pressesBegan:withEvent: 以突出显示您的控件。

因为 UIControl 符合 UIFocusEnvironment 协议(通过 UIView),您可以覆盖 didUpdateFocusInContext:withAnimationCoordinator: 以根据控件是否具有焦点来更新控件的外观.

在过去的几周里,我用我的 SVG 渲染库 SVGgh, so I have somewhat of a feeling for this. The issue is that there is what I think is a new or newish kind of action: UIControlEventPrimaryActionTriggered that gets sent out when the control wants to communicate a commitment of action, as in this response to the completion of a UIPress in my GHButton class 为我打包的小部件添加了 tvOS 支持。请记住在故事板中为这个新动作连接一个选择器。

-(void) pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{
    [self sendActionsForControlEvents:UIControlEventPrimaryActionTriggered];
    self.beingPressed = NO;
    self.selected = self.selected;
}

但是在分段控制模拟中,动作不是在按下按钮时设置的,而是在焦点部分发生变化时设置的,如下面的代码(为清楚起见进行了大量编辑)来自我的 GHSegmentedControl class:

- (BOOL)shouldUpdateFocusInContext:(UIFocusUpdateContext *)context
{
    BOOL result =  NO;
    if(context.nextFocusedView == self)
    {
        result = YES;
        [self highlight:YES];
        if(context.focusHeading == UIFocusHeadingRight)
        {
            [self incrementValue];

            [self.parentContent.control setNeedsFocusUpdate];

            [self sendActionsForControlEvents:UIControlEventValueChanged];
        }
        else if(context.focusHeading == UIFocusHeadingLeft)
        {
            [self decrementValue];
            [self.parentContent.control setNeedsFocusUpdate];
            [self sendActionsForControlEvents:UIControlEventValueChanged];
        }
    }

    return result;
}

既然我想到了,我也可能应该在分段控件中发送 UIControlEventPrimaryActionTriggered 操作,但 UIControlEventValueChanged 似乎按我预期的方式工作。