MST

星途 面试题库

面试题:SwiftUI下3D Touch与Peek and Pop跨平台及适配性问题

考虑到SwiftUI应用可能运行在不同的iOS设备上,且部分旧设备可能不支持3D Touch,如何设计一套通用的交互逻辑,既能在支持3D Touch的设备上实现Peek and Pop功能,又能在不支持的设备上提供相近的交互体验?请详细说明设计思路及代码实现架构,包括如何处理设备兼容性检测及不同交互逻辑的切换。
32.0万 热度难度
编程语言Swift

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 设备兼容性检测:通过检测设备是否支持3D Touch来决定使用何种交互逻辑。在SwiftUI中,可以利用UIDevice类的相关属性进行检测。
  2. 不同交互逻辑切换
    • 支持3D Touch设备:实现Peek and Pop功能,即通过按压屏幕进行预览(Peek),进一步按压进行深入操作(Pop)。
    • 不支持3D Touch设备:可以通过长按手势模拟Peek功能,通过点击模拟Pop功能。

代码实现架构

  1. 检测设备是否支持3D Touch
import UIKit

func is3DTouchSupported() -> Bool {
    if #available(iOS 13.0, *) {
        return UIScreen.main.traitCollection.forceTouchCapability == .available
    } else {
        return UIDevice.current.hasForceTouchCapability
    }
}
  1. 创建通用交互逻辑视图
import SwiftUI

struct UniversalInteractionView<Content: View>: View {
    let content: Content
    @State private var isPreviewing = false
    @State private var isShowingDetail = false

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
        if is3DTouchSupported() {
            // 支持3D Touch设备的交互逻辑
            content
               .simultaneousGesture(
                    LongPressGesture(minimumDuration: 0.2)
                       .sequenced(before: DragGesture())
                       .updating($isPreviewing) { value, state, _ in
                            state = value.first?.isFinished == true
                        }
                       .onEnded { value in
                            if value.first?.isFinished == true {
                                isShowingDetail = true
                            }
                        }
                )
               .sheet(isPresented: $isShowingDetail) {
                    content
                }
        } else {
            // 不支持3D Touch设备的交互逻辑
            content
               .gesture(
                    LongPressGesture(minimumDuration: 0.2)
                       .onEnded { _ in
                            isPreviewing = true
                        }
                )
               .sheet(isPresented: $isPreviewing) {
                    content
                       .gesture(
                            TapGesture()
                               .onEnded {
                                    isPreviewing = false
                                }
                        )
                }
        }
    }
}
  1. 使用通用交互逻辑视图
struct ContentView: View {
    var body: some View {
        UniversalInteractionView {
            Text("这是一个示例内容")
        }
    }
}

在上述代码中:

  • is3DTouchSupported函数用于检测设备是否支持3D Touch。
  • UniversalInteractionView是一个通用的交互逻辑视图,根据设备是否支持3D Touch来决定使用不同的手势交互逻辑。
  • 在支持3D Touch的设备上,使用长按结合拖动手势模拟Peek and Pop。
  • 在不支持3D Touch的设备上,使用长按时显示预览,点击关闭预览来模拟相近的交互体验。