使用:
我只想检测下面 URLImage 上的点击手势
JFYI 我对 Xcode、Swift 和 SwiftUI 非常陌生(不到 3 周)。
URLImage(URL(string: channel.thumbnail)!,
delay: 0.25,
processors: [ Resize(size: CGSize(width:isFocused ? 300.0 : 225.0, height:isFocused ? 300.0 : 225.0), scale: UIScreen.main.scale) ],
content: {
$0.image
.resizable()
.aspectRatio(contentMode: .fill)
.clipped()
})
.frame(width: isFocused ? 300.0 : 250.0, height:isFocused ? 300.0 : 250.0)
.clipShape(Circle())
.overlay(
Circle().stroke( isFocused ? Color.white : Color.black, lineWidth: 8))
.shadow(radius:5)
.focusable(true, onFocusChange:{ (isFocused) in
withAnimation(.easeInOut(duration:0.3)){
self.isFocused = isFocused
}
if(isFocused){
self.manager.bannerChannel = self.channel
print(self.manager.bannerChannel)
self.manager.loadchannelEPG(id: self.channel.id)
}
})
.padding(20)
}
或 Button 但随后可聚焦在该按钮上的按钮不会运行。
由于手势可用,也许有一种我无法弄清楚的使用手势的方法。
或者
如果有一种方法可以在按钮上获取焦点(尽管这是不太受欢迎的选择,因为这会改变我想要实现的外观)。
最佳答案
这是可能的,但不适合胆小的人。我想出了一个可能对您有所帮助的通用解决方案。我希望在下一次 swiftUI 更新中,Apple 添加了一种更好的方法来为 tvOS 附加点击事件,并且此代码可以归入它所属的垃圾箱。
如何做到这一点的高级解释是创建一个捕获焦点和单击事件的 UIView,然后创建一个 UIViewRepresentable 以便 swiftUI 可以使用该 View 。然后 View 被添加到 ZStack 中的布局中,因此它被隐藏了,但是您可以接收焦点并响应单击事件,就好像用户真的在与您真正的 swiftUI 组件进行交互一样。
首先,我需要制作一个 UIView 来捕获事件。
class ClickableHackView: UIView {
weak var delegate: ClickableHackDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
}
override func pressesEnded(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
if event?.allPresses.map({ $0.type }).contains(.select) ?? false {
delegate?.clicked()
} else {
superview?.pressesEnded(presses, with: event)
}
}
override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
delegate?.focus(focused: isFocused)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var canBecomeFocused: Bool {
return true
}
}
~可点击的委托(delegate):
protocol ClickableHackDelegate: class {
func focus(focused: Bool)
func clicked()
}
然后为我的 View 做一个 swiftui 扩展struct ClickableHack: UIViewRepresentable {
@Binding var focused: Bool
let onClick: () -> Void
func makeUIView(context: UIViewRepresentableContext<ClickableHack>) -> UIView {
let clickableView = ClickableHackView()
clickableView.delegate = context.coordinator
return clickableView
}
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<ClickableHack>) {
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
class Coordinator: NSObject, ClickableHackDelegate {
private let control: ClickableHack
init(_ control: ClickableHack) {
self.control = control
super.init()
}
func focus(focused: Bool) {
control.focused = focused
}
func clicked() {
control.onClick()
}
}
}
然后我制作了一个更友好的 swiftui 包装器,这样我就可以传入任何我想要可聚焦和可点击的组件struct Clickable<Content>: View where Content : View {
let focused: Binding<Bool>
let content: () -> Content
let onClick: () -> Void
@inlinable public init(focused: Binding<Bool>, onClick: @escaping () -> Void, @ViewBuilder content: @escaping () -> Content) {
self.content = content
self.focused = focused
self.onClick = onClick
}
var body: some View {
ZStack {
ClickableHack(focused: focused, onClick: onClick)
content()
}
}
}
示例用法:struct ClickableTest: View {
@State var focused1: Bool = false
@State var focused2: Bool = false
var body: some View {
HStack {
Clickable(focused: self.$focused1, onClick: {
print("clicked 1")
}) {
Text("Clickable 1")
.foregroundColor(self.focused1 ? Color.red : Color.black)
}
Clickable(focused: self.$focused2, onClick: {
print("clicked 2")
}) {
Text("Clickable 2")
.foregroundColor(self.focused2 ? Color.red : Color.black)
}
}
}
}
关于swift - 如何在 SwiftUI tvOS 中检测 'Click' 手势,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59200396/