Итерация через подвесития контента ViewBuilder и использование контента непосредственно [дублировать]IOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Итерация через подвесития контента ViewBuilder и использование контента непосредственно [дублировать]

Сообщение Anonymous »

Я пытаюсь создать пользовательский Tabview. Я хочу сделать поведение таким же, как и Tabview по умолчанию, в том смысле, что я хочу использовать Iterate и Content для любых пользовательских абитемов и генерировать из него CustomTabView.

Код: Выделить всё

public enum CustomTabVariant {
case filled
case scrollable
}

public struct CustomTabView: View {
@Binding private var activeIndex: Int
private let itemLabels: [String]
private let variant: CustomTabVariant

public init(activeIndex: Binding,
itemLabels: [String],
variant: CustomTabVariant) {
self._activeIndex = activeIndex
self.itemLabels = itemLabels
self.variant = variant
}

@ViewBuilder
public var body: some View {
switch variant {
case .filled:
variantFilled
case .wrapText:
variantScrollable
}
}

private var variantFilled: some View {
HStack(spacing: 0) {
ForEach(Array(itemLabels.enumerated()), id: \.offset) { id, label in
Button { activeIndex = Int(id) } label: {
CustomTabItem(isActive: Binding(get: { activeIndex == Int(id) },
set: { if $0 { activeIndex = Int(id) } }),
title: label,
content: { Text("Content 1") } )
}
}
}
}

private var variantScrollable: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 0) {
ForEach(Array(itemLabels.enumerated()), id: \.offset) { id, label in
Button { activeIndex = Int(id) } label: {
CustomTabItem(isActive: Binding(get: { activeIndex == Int(id) },
set: { if $0 { activeIndex = Int(id) } }),
title: label,
content: { Text("Content 1") } )
}
}
}
}
.background {
VStack {
Spacer()
Color.black.opacity(0.8).frame(height: 1)
}
}
}
}

public struct CustomTabItem: View {
@Binding var isActive: Bool
let title: String
let content: () -> Content // This will hold the view when the tab is active. Not doing anything right now

public init(isActive: Binding,
title: String,
@ViewBuilder content: @escaping () -> Content) {
self._isActive = isActive
self.title = title
self.content = content
}

var body: some View {
if isActive {
Text(title)
.font(.system(size: 14, weight: .bold))
.foregroundStyle(Color.blue)
.frame(maxWidth: .infinity)
.padding(.all, 12)

.background {
VStack {
Spacer()
Color.blue.frame(height: 2)
}
.background(Color.blue.opacity(0.5))
}
} else {
Text(title)
.font(.system(size: 13))
.foregroundStyle(Color.black.opacity(0.8))
.frame(maxWidth: .infinity)
.padding(.all, 12)
.background {
VStack {
Spacer()
Color.black.opacity(0.8).frame(height: 1)
}
.background(Color.white)
}
}
}
}
Это работает прямо сейчас, но в основном логика для переключения обрабатывается за пределами CustomTabView, связывая ActiveIndex . То, что я хочу сделать, это обрабатывать контент так же, как и Tabview Swiftui, обрабатывая его контент, показывая содержимое его вкладки. В основном я хочу рефакторировать это: < /p>
struct CustomTabPreviewView: View {

@State private var activeIndex: Int = 0

var body: some View {
VStack {
CustomTabView(activeIndex: $activeIndex, itemLabels: itemLabels, variant: .scrollable)
Text("Active index: \(activeIndex)")
Spacer()
}
}
}

private let itemLabels: [String] = Array(1...10).map { "Tab \($0)" }

< /code>
к чему -то вроде: < /p>
struct CustomTabPreviewView: View {

@State private var activeIndex: Int = 0

var body: some View {
VStack {
CustomTabView(activeIndex: $activeIndex, variant: .scrollable) {
CustomTabItem(label: "Tab 1") { Text("Active index: 0") }
CustomTabItem(label: "Tab 2") { Text("Active index: 1") }
CustomTabItem(label: "Tab 3") { Text("Active index: 2") }
CustomTabItem(label: "Tab 4") { Text("Active index: 3") }
CustomTabItem(label: "Tab 5") { Text("Active index: 4") }
CustomTabItem(label: "Tab 6") { Text("Active index: 5") }
CustomTabItem(label: "Tab 7") { Text("Active index: 6") }
CustomTabItem(label: "Tab 8") { Text("Active index: 7") }
CustomTabItem(label: "Tab 9") { Text("Active index: 8") }
CustomTabItem(label: "Tab 10") { Text("Active index: 9") }
}
Spacer()
}
}
}

private let itemLabels: [String] = Array(1...10).map { "Tab \($0)" }

< /code>
Можете ли вы помочь мне в этом направлении? Спасибо.>

Подробнее здесь: https://stackoverflow.com/questions/796 ... content-of
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • SwiftUI. Как фильтровать дочерние элементы ViewBuilder?
    Anonymous » » в форуме IOS
    0 Ответы
    35 Просмотры
    Последнее сообщение Anonymous
  • Необязательное закрытие @ViewBuilder
    Anonymous » » в форуме IOS
    0 Ответы
    64 Просмотры
    Последнее сообщение Anonymous
  • Необязательное закрытие @ViewBuilder
    Anonymous » » в форуме IOS
    0 Ответы
    20 Просмотры
    Последнее сообщение Anonymous
  • Необязательное закрытие @ViewBuilder
    Anonymous » » в форуме IOS
    0 Ответы
    21 Просмотры
    Последнее сообщение Anonymous
  • Swiftui, передавая представление в виде параметров в @ViewBuilder
    Anonymous » » в форуме IOS
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous

Вернуться в «IOS»