Featured image of post tvOS 开发实践 - SwiftUI篇

tvOS 开发实践 - SwiftUI篇

记录使用 SwiftUI 开发 tvOS app时遇到的问题和解决方案

焦点非对齐移动

默认tvOS焦点移动是需要移动方向上有能获取焦点的button,假如button是左右靠边对齐的,就移动不上去。需要使用focusSetion把button所在的整行范围变成可焦点识别的,才能自动移动到靠边的button上。

示例:

VStack {
    HStack {
        Button {} label: {
            Text("test")
        }
    }
    .frame(maxWidth: .infinity, alignment: .trailing)
    .focusSection()

    Button {} label: {
        Text("Save")
    }
}

实现Parralw效果

需要使用开源库ParallaxView编写自定义控件实现

优化滚动列表性能

SwiftUI滚动列表中有异步加载的图片时,向下快速滚动会停顿,不能持续滚动,看着像是tvOS焦点切换到indicator时出现了问题。要解决只能改为使用UICollectionView来实现滚动列表,推荐使用第三方开源的ASCollectionViewSwiftUIX来实现。

tabbar随内容滚动

需要借助Introspect

import Foundation
import SwiftUI

struct TabBarScrollModifier: ViewModifier {
    func body(content: Content) -> some View {
        content.introspectViewController { viewController in
            let scrollView = findScrollViewIn(view: viewController.view)
            if let scrollView = scrollView as? UIScrollView {
                viewController.setContentScrollView(scrollView, for: .top)
            }
        }
    }
    
    private func findScrollViewIn(view : UIView?) -> UIView? {
        guard let view = view else { return nil }
        
        if view.subviews.count <= 0 {
            return nil
        }
        
        for sub in view.subviews {
            if sub is UIScrollView || sub is UICollectionView {
                return sub
            }
            
            
            if let item = findScrollViewIn(view: sub) {
                return item
            }
        }
        
        return nil
    }
}

extension View {
    
    func tabBarScroll() -> some View {
        modifier(TabBarScrollModifier())
    }
    
}

在内容的ScrollView中调用:

ScrollView {
    // content
}
.tabBarScroll()

onLongPressGesture导致跳转失效

假如在 NavigationLink 上使用 onLongPressGesture,那么 NavigartionLink 的跳转会失效

NavigationLink{
    EmptyView()
} label: {
    Text("Click")
}
.onLongPressGesture {
    // 加上这句会没法触发跳转
    print("long press")
}

看网上说法这是appletv的bug,可在 onLongPressGesture 前面加上 onPlayPauseCommand 来避免这问题

NavigationLink{
    EmptyView()
} label: {
    Text("Click")
}
.onPlayPauseCommand {
    // fixed navigate!!!
}
.onLongPressGesture {
    print("long press")
}

如何本地修改导入的swift package

需要把swift package先下载到本地,然后在finder中找到文件夹,直接拖到xcode项目根目录中

这样修改本地代码,就可以在xcode中看到修改后的效果

Built with Hugo
主题 StackJimmy 设计