#ios #swift #swiftui
Вопрос:
Редактировать: По сути, я не могу понять, как вернуть значение в списке plist на основе ключа.
Я пытаюсь создать приложение для себя в swift, которое на данный момент имеет особый фокус — случайным образом выбрать изображение, которое я поместил в папку «Ресурсы», и показать это изображение. Там будет большое количество этих изображений, поэтому вручную вводить параметры не будет работать.
Шаги, которые, по моему мнению, мне нужны:
- пусть переменная A = «Элемент (arc4random_uniform(#))»
- пусть переменная B = [Значение из списка, соответствующее ключу из переменной A]
- Изображение(переменная B)
Шаг 2-это тот, который я не могу понять.
У меня есть список, который изложен примерно так:
Я знаю, как сгенерировать случайный ключ с помощью приведенного ниже.
let variableA = "Item (arc4random_uniform(#))"
// # is the number of images in the plist
Я знаю, как создать изображение актива, просто используя приведенное ниже.
var body: some View {
Image(variableB)
.resizable()
.scaledToFit()
}
Чего я не знаю и не могу понять, так это как заставить приложение генерировать случайный «Элемент #» из первой части, затем выбрать соответствующее имя из столбца значений списка, используя «Элемент #» в качестве ключевого столбца, а затем использовать это соответствующее значение имени для создания изображения.
ИЗМЕНИТЬ: Я обновил код, и теперь он выглядит следующим образом. Это выдает ошибку в строке с «do {» , в которой говорится, что «Закрытие, содержащее оператор потока управления, не может использоваться с построителем результатов»ViewBuilder»».
import SwiftUI
import UIKit
struct ContentView: View {
@State private var variableB = ""
var body: some View {
let plist = "All Relics"
do {
let array = try PropertyListDecoder().decode([String].self, from: Data(plist.utf8))
let imageName = array.randomElement()!
print(imageName)
} catch { print(error) }
Image(variableB)
.onAppear {
if let array = try? PropertyListDecoder().decode([String].self, from: data),
let imageName = array.randomElement() {
variableB = imageName
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Ответ №1:
Прежде всего arc4random_uniform
устарел. Начиная с Swift 4 существуют собственные API
Это ваш список, содержащий 3 пункта
let plist = """
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>Some Name</string>
<string>Some Other Name</string>
<string>Something Different</string>
</array>
</plist>
"""
Просто расшифруйте список с PropertyListDecoder
помощью to [String]
и получите randomElement()
do {
let array = try PropertyListDecoder().decode([String].self, from: Data(plist.utf8))
let imageName = array.randomElement()!
print(imageName)
} catch { print(error) }
В среде SwiftUI создайте @State
переменную
@State private var variableB = ""
и, например, в .onAppear
получить случайную строку и назначить ее variableB
( data
является Data
представлением списка свойств)
.onAppear {
if let url = Bundle.main.url(forResource: "All Relics", withExtension: "plist"),
let data = try? Data(contentsOf: url),
let array = try? PropertyListDecoder().decode([String].self, from: data),
let imageName = array.randomElement() {
variableB = imageName
}
}
Комментарии:
1. Я ценю эту информацию. Я попытался собрать все это вместе, но я получаю «Закрытие, содержащее оператор потока управления, не может использоваться с построителем результатов» ViewBuilder «» в строке с «do {«и «Ожидаемое» другое «после условия» охрана «»после строки с» пусть имя_имя = массив.randomElement() {»
2. Моя вина, замени
guard
наif
. Первый фрагмент-это просто пример, который нужно протестировать на игровой площадке.3. Изменить: Я добавляю свой обновленный код в основной пост. Когда вы говорите, что «первый фрагмент» — это просто пример, вы имеете в виду список или часть » сделать {«? Часть «do {«- единственная, возвращающая ошибку «Закрытие, содержащее оператор потока управления, не может использоваться с построителем результатов» ViewBuilder «» в той же строке. Я попытался погуглить эту точную фразу, но она привела только к одному результату, и я не уверен, что понимаю, что она пытается мне сказать.
4. Вы не можете использовать (весь) первый фрагмент в теле представления SwiftUI. Это просто показывает, как декодировать список
5. Ах. Итак, как же мне тогда это обойти? Фрагменты, которые я собрал вместе, были взяты из учебных пособий, которые я смотрел онлайн и пытался собрать воедино небольшие фрагменты здесь и там.