小编Ant*_*ton的帖子

SwiftUI 视图不基于@ObservedObject 更新

在下面的代码中,观察到的对象被更新,但观察它的视图没有更新。知道为什么吗?

代码在屏幕上显示 10 个数字 (0..<10) 和一个按钮。每当按下按钮时,它会随机选择 10 个数字之一并翻转其可见性(可见?隐藏,反之亦然)。

打印语句显示按钮正在更新数字,但视图不会相应更新。我知道更新数组中的值不会改变数组值本身,所以我使用手册objectWillChange.send()调用。我原以为应该触发更新,但屏幕永远不会改变。

任何的想法?我对NumberLine用作类或结构的解决方案感兴趣,或者根本不使用NumberLine类型,而只是在ContentView结构中使用数组变量。

截屏

这是代码:

import SwiftUI

struct ContentView: View {

    @ObservedObject var numberLine = NumberLine()

    var body: some View {
        VStack {
            HStack {
                ForEach(0 ..< numberLine.visible.count) { number in
                    if self.numberLine.visible[number] {
                        Text(String(number)).font(.title).padding(5)
                    }
                }
            }.padding()

            Button(action: {
                let index = Int.random(in: 0 ..< self.numberLine.visible.count)
                self.numberLine.objectWillChange.send()
                self.numberLine.visible[index].toggle()
                print("\(index) now \(self.numberLine.visible[index] ? "shown" : "hidden")")
            }) {
                Text("Change")
            }.padding()
        }
    }
}

class NumberLine: ObservableObject …
Run Code Online (Sandbox Code Playgroud)

arrays ios swiftui observableobject

20
推荐指数
3
解决办法
2万
查看次数

减少 SwiftUI 中文本的行距

对于某些字体,内置行距过大令人不快。

SwiftUI 为我们提供了调整文本行间距的Text修饰符.lineSpacing()(也称为引导,与引导/拖尾无关)。它的值指定放置在连续文本行之间的额外间距的点数,因此不会.lineSpacing(0)产生任何变化。不幸的是,它似乎对负值没有反应;.lineSpacing(-10)产生与 相同的结果lineSpacing(0)

有没有人知道一种在不使用 UIKit 的情况下减少 SwiftUI 中行间距的方法?

text line-spacing swiftui

14
推荐指数
2
解决办法
1151
查看次数

用音频录制 Xcode Simulator 的视频?

我需要录制我的应用程序的视频以用于应用程序商店中的预览。对我来说,展示实际的应用程序音频至关重要(因为它是针对音乐家的交互式教育应用程序)。

\n

Xcode Simulator 12.5 有一个很棒的新功能,可以轻松录制视频\xe2\x80\xa6\xc2\xa0,但录制的视频不包含声音。

\n

有谁知道用应用程序声音录制应用程序视频演示的好方法?

\n

(使用 QuickTime 和实际的 iPhone/iPad\xe2\x80\xa6 很容易做到,但这只是一个解决方案,如果您碰巧有一组与每个所需的应用程序预览分辨率匹配的设备\xe2\x80\ xa6,我不知道。)

\n

更新:我尝试单独录制音频,认为我总是可以将其与 Final Cut/Premiere 等中的视频合并。为此,我安装了BlackHole;我的计划是使用 QuickTime Player 来录制音频,选择 BlackHole 作为音频源。不幸的是,BlackHole 似乎不包括 Simulator 的音频输出。

\n

audio video simulator preview ios

11
推荐指数
2
解决办法
4633
查看次数

在 SwiftUI 中以固有尺寸显示分段选取器

在 SwiftUI 中,Pickerof 样式SegmentedPickerStyle占据其封闭视图的整个宽度。我怎样才能让它只占据它需要的宽度?

考虑一下: 分段拾取器 它是由以下代码生成的:

struct ContentView: View {
    @State var value = 1
    var body: some View {
        Picker("Value", selection: $value) {
            Text("One").tag(1)
            Text("Two").tag(2)
        }
        .pickerStyle(SegmentedPickerStyle())
        .padding()
    }
}
Run Code Online (Sandbox Code Playgroud)

如何从两个选择器选择中删除较大的边距,使选择器仅达到所需的宽度?这似乎是一个非常基本的问题,但我却找不到答案。

picker width ios segmentedcontrol swiftui

10
推荐指数
1
解决办法
2931
查看次数

SwiftUI 中的动画文本

SwiftUI 具有出色的动画功能,但它处理TextView 内容更改的方式存在问题。它对文本框的变化进行动画处理,但在没有动画的情况下立即更改文本。因此,当TextView的内容变长时,动画过渡会导致省略号 (...) 出现,直到文本框达到其全宽。例如,在这个小应用程序中,按下Toggle按钮在较短和较长的文本之间切换

这是代码:

import SwiftUI

struct ContentView: View {
    @State var shortString = true
    var body: some View {
        VStack {
            Text(shortString ? "This is short." : "This is considerably longer.").font(.title)
                .animation(.easeInOut(duration:1.0))
            Button(action: {self.shortString.toggle()}) {
                Text("Toggle").padding()
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是:如何避免省略号?将一个字符串动画化为两个字符串时,情况更糟,因为短字符串在动画化为较长字符串时完全被省略号替换。

例如,一种可能性是通过添加修饰符,.id(self.shortString ? 0 : 1)然后添加修饰符,为处于一种或另一种状态的视图分配一个单独的 id .transition()。这会将文本视为两个不同的视图,之前和之后。不幸的是,在我的情况下,我需要在更改期间移动文本位置,而不同的 id 使动画变得不可能。

我想解决方案是创造性地使用AnimatableData. …

animation text ellipsis swiftui

9
推荐指数
2
解决办法
3876
查看次数

可供 AVSpeechSynthesis 在 iOS 中使用的已安装语音的可用性

我希望能够测试哪些文本转语音可供我的 iOS 应用程序与 AVSpeechSynthesis 一起使用。生成已安装声音的列表很容易,但 Apple 将其中一些设置为禁止应用程序使用,我想知道哪些。

例如,考虑以下测试代码 (swift 5.1):

import AVFoundation

...

func voiceTest() {
    let speechSynthesizer = AVSpeechSynthesizer()
    let voices = AVSpeechSynthesisVoice.speechVoices()
    for voice in voices where voice.language == "en-US" {
        print("\(voice.language) - \(voice.name) - \(voice.quality.rawValue) [\(voice.identifier)]")
        let phrase = "The voice you're now listening to is the one called \(voice.name)."
        let utterance = AVSpeechUtterance(string: phrase)
        utterance.voice = voice
        speechSynthesizer.speak(utterance)
    }
}
Run Code Online (Sandbox Code Playgroud)

当我打电话时voiceTest(),控制台输出是这样的:

en-US - Nicky (Enhanced) - 2 [com.apple.ttsbundle.siri_female_en-US_premium]
en-US - Aaron - 1 [com.apple.ttsbundle.siri_male_en-US_compact] …
Run Code Online (Sandbox Code Playgroud)

voice text-to-speech ios siri avspeechsynthesizer

6
推荐指数
1
解决办法
1066
查看次数

自动加载 AVSpeech?Synthesizer 的声音

是否可以在 iOS 应用程序中自动加载新的语音合成语音?多种高质量的“增强”声音可供下载Settings > Accessibility > Spoken Content > Voices > English。我想使用其中一种高质量的应用程序,但不想向应用程序用户解释他们必须通过深入“设置”导航来手动下载它们。

\n\n

Siri 声音似乎是我手机上预装的唯一高质量声音,不幸的是 Apple 不允许我们在 AVSpeech\xe2\x80\x8bSynthesizer 中使用这些声音。(选择其中之一作为 AVSpeechSynthesisVoice\xe2\x80\x94 例如

\n\n
let utterance = AVSpeechUtterance(string: "This is a test.")\nutterance.voice = AVSpeechSynthesisVoice(identifier: "com.apple.ttsbundle.siri_female_en-US_premium")\nspeechSynthesizer.speak(utterance)\n
Run Code Online (Sandbox Code Playgroud)\n\n

没有影响;而是使用质量较低的默认语音。)

\n

voice text-to-speech ios avspeechsynthesizer swift

5
推荐指数
0
解决办法
366
查看次数

SwiftUI - 通过嵌套引用类型传播更改通知

我想将 SwiftUI 中的 ObservableObject 行为扩展到嵌套类,我正在寻找正确的方法来做到这一点。它可以使用Combine“手动”完成,但我想使用SwiftUI有一种更简洁的方法,我希望你能指出我正确的方向。这就是我的意思……

下面是 ObservableObject 的一个典型应用,它使 View 动态响应引用类型的变化。点击按钮切换showText值,使文本在屏幕上出现/消失:

import SwiftUI

class MyClass: ObservableObject {
    @Published var showText = false
}


struct ContentView: View {

    @ObservedObject var instance = MyClass()

    var body: some View {
        VStack(spacing: 10) {
            Button(action: {
                print(self.instance.showText)
                self.instance.showText.toggle()
            }) {
                Text("BUTTON").bold().padding()
                    .foregroundColor(.white)
                    .background(Color.red)
            }
            if instance.showText {
                Text("Hello, World!")
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这工作正常。

但是下面的修改呢,其中包含的类showText是 an InnerClass,它本身包含在 an 中OuterClass?按钮切换showText得很好,但值更改的通知不再通过OuterClass实例传播到视图,因此视图根本不再显示文本。

import SwiftUI

class OuterClass: ObservableObject …
Run Code Online (Sandbox Code Playgroud)

propagation swiftui combine observableobject

5
推荐指数
1
解决办法
912
查看次数

简化 Xcode 中的 SwiftUI 预览

我的应用程序通常运行很多代码,我想在预览中跳过它们。代码耗时且没有可见效果(例如初始化音频设备)。我正在尝试弄清楚如何跳过它进行预览。

\n\n

有一种简单的方法可以使用 DEBUG 宏仅在应用程序的生产版本中运行代码。但我不知道非预览版有什么类似的东西(因为预览版可能会构建与非预览版相同的代码)。

\n\n

我认为previewMode在我的 ViewModel 中设置一个变量 是可行的。这样我就可以只在 PreviewProvider 中将其设置为 true:

\n\n
struct MainView_Previews: PreviewProvider {\n\n    static var previews: some View {\n        let vm = ViewModel(previewMode: true)\n        return MainView(viewModel: vm)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我在 SceneDelegate 中创建 ViewModel 时,我可以设置previewModefalse

\n\n
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {\n\n    let vm = ViewModel(previewMode: false)\n    let mainView = MainView(viewModel: vm)\n\n    // Use a UIHostingController as window root view controller.\n    if let windowScene = …
Run Code Online (Sandbox Code Playgroud)

xcode preview swiftui

5
推荐指数
1
解决办法
1245
查看次数

当 TapGesture 也出现时,SwiftUI LongPressGesture 需要很长时间才能识别

我想在同一项目上识别TapGesture和。LongPressGesture它工作正常,但有以下例外: the LongPressGesturealone 在我指定的持续时间后响应,即 0.25 秒,但是当我将它与 结合使用时TapGesture,至少需要 1 秒\xe2\x80\x94我找不到使其响应更快的方法。这是一个演示:

\n

在此输入图像描述

\n

这是它的代码:

\n
struct ContentView: View {\n    @State var message = ""\n\n    var body: some View {\n        Circle()\n            .fill(Color.yellow)\n            .frame(width: 150, height: 150)\n            .onTapGesture(count: 1) {\n                message = "TAP"\n            }\n            .onLongPressGesture(minimumDuration: 0.25) {\n                message = "LONG\\nPRESS"\n            }\n            .overlay(Text(message)\n                        .font(.title).bold()\n                        .multilineTextAlignment(.center)\n                        .allowsHitTesting(false))\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,除了长按的持续时间(远长于 0.25 秒)之外,它工作正常。

\n

有任何想法吗?提前致谢!

\n

duration gesture ios long-press swiftui

5
推荐指数
1
解决办法
2380
查看次数