使用:
我只想在下面的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)
}
由于可以使用手势,也许有一种使用我无法弄清楚的手势的方法。
或
如果有一种方法可以将焦点放到按钮上(尽管这是最不受欢迎的选择,因为这会改变我想要的外观)。
有可能,但不是因为胆小的人。我想出了一个可能对您有所帮助的通用解决方案。我希望在下一个swiftUI更新中,Apple可以为tvOS附加单击事件的更好方法,并且此代码可以移交给它所属的垃圾箱。
有关如何执行此操作的高级解释是,制作一个捕获焦点和单击事件的UIView,然后制作一个UIViewRepresentable,以便swiftUI可以使用该视图。然后将视图添加到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 } }
可点击的委托人:
protocol ClickableHackDelegate: class { func focus(focused: Bool) func clicked() }
然后为我的视图添加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)
}
}
}
}