ここでいう Swift Playgrounds はXcodeに付属のPlaygroundではなく、iPadアプリとしての Swift Playgroundsを指しています。
以降、 Swift Playgrounds は 「iPadアプリのSwift Playground」、 Xcode Playground はXcodeに付属のPlaygroundと使い分けます。
Swift Playgroundのmainファイルでは、Previewを UIHostingController で描画するようにします。
Swift Playgroundsでのmainと、その他のファイルとでは、別Module扱いになるため、 public 修飾子ないものにはアクセスできません。 import はいらない。
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)extensionForEachwhere Data == Range<Int>, ID == Int, Content :View {
/// Creates an instance that computes views on demand over a *constant*/// range.////// This instance only reads the initial value of `data` and so it does not/// need to identify views across updates.////// To compute views on demand over a dynamic range use/// `ForEach(_:id:content:)`.publicinit(_ data:Range<Int>, @ViewBuildercontent:@escaping (Int)->Content)
}
/** * Creates a new {@link LiveData} object does not emit a value until the source LiveData value * has been changed. The value is considered changed if {@code equals()} yields {@code false}. * * @param source the input {@link LiveData} * @param <X> the generic type parameter of {@code source} * @return a new {@link LiveData} of type {@code X} */@MainThread@NonNullpublicstatic <X> LiveData<X> distinctUntilChanged(@NonNull LiveData<X> source) {
final MediatorLiveData<X> outputLiveData = new MediatorLiveData<>();
outputLiveData.addSource(source, new Observer<X>() {
boolean mFirstTime = true;
@Overridepublicvoid onChanged(X currentValue) {
final X previousValue = outputLiveData.getValue();
if (mFirstTime
|| (previousValue == null && currentValue != null)
|| (previousValue != null && !previousValue.equals(currentValue))) {
mFirstTime = false;
outputLiveData.setValue(currentValue);
}
}
});
return outputLiveData;
}
Starting March 27, 2019, all new apps and app updates for iPhone or iPad, including universal apps, must be built with the iOS 12.1 SDK or later and support iPhone XS Max or the 12.9-inch iPad Pro (3rd generation). Screenshots for these devices will also be required.