В SwiftUI есть простой способ выровнять более одного представления в ZStack

У меня есть представление, и я хочу добавить к нему два значка: вверху справа и внизу справа. Мне это удалось:

Я использовал два стека ZStacks:

      ZStack(alignment: .bottomTrailing)
{
    ZStack(alignment: .topTrailing)
    {
        Image(item.thumbnailImage)
            .clipShape(Circle())
            .overlay(Circle()
                        .stroke(Color.gray, lineWidth: 2))
        
        if item.isFavorite
        {
            Image(systemName: "star.fill")
                .foregroundColor(.yellow)
                .offset(x: 7, y: -7)
        }
    }
    
    if item.ordered
    {
        Image(systemName: "checkmark.square.fill")
            .offset(x: 7, y: 7)
    }
}

Но у меня такое чувство, что должен быть способ попроще, чем вложение ZStacks внутрь. Кроме того, похоже, что маленькие значки не выровнены по центру x. Я, вероятно, смогу исправить это, изменив смещение, но это сделало бы код еще более неуклюжим.

Есть способ попроще?

2 ответа

Используйте только один Zstack и заверните две иконки в VStack.

              `ZStack`(alignment: .trailing) {
            Circle()
             .stroke(Color.gray, lineWidth: 2)

            VStack {
                Image(systemName: "star.fill")
                Spacer()
                Image(systemName: "checkmark.square.fill")
            }
            // Adjust the position of star and checkmark
            .offset(x: -10)
        }
        .frame(width: 100, height: 100)

Вы можете использовать модификатор, например:

      import PlaygroundSupport
import SwiftUI

PlaygroundPage.current.setLiveView(
    Circle()
        .strokeBorder(Color.gray, lineWidth: 6)
        .frame(width: 44, height: 44)
        .overlay(
            Image(systemName: "star.fill")
                .foregroundColor(.yellow)
                .offset(x: 7, y: -7),
            alignment: .topTrailing)
        .overlay(
            Image(systemName: "checkmark.square.fill")
                .offset(x: 7, y: 7),
            alignment: .bottomTrailing)
        .padding()
)

Если ваша цель развертывания - iOS 15 или новее (или согласованная версия macOS, tvOS или watchOS), вы можете использовать ViewBuilder версия overlay вместо:

      import PlaygroundSupport
import SwiftUI

PlaygroundPage.current.setLiveView(
    Circle()
        .strokeBorder(Color.gray, lineWidth: 6)
        .frame(width: 44, height: 44)
        .overlay(alignment: .topTrailing) {
            Image(systemName: "star.fill")
                .foregroundColor(.yellow)
                .offset(x: 7, y: -7)
        }
        .overlay(alignment: .bottomTrailing) {
            Image(systemName: "checkmark.square.fill")
                .offset(x: 7, y: 7)
        }
        .padding()
)

Мы можем использовать предложение lorem для выравнивания центров символов с помощью. Тогда мы можем вычленить два offset модификаторы в padding на VStack.

      import PlaygroundSupport
import SwiftUI

PlaygroundPage.current.setLiveView(
    Circle()
        .strokeBorder(Color.gray, lineWidth: 6)
        .frame(width: 44, height: 44)
        .overlay(
            VStack(spacing: 0) {
                Image(systemName: "star.fill")
                    .foregroundColor(.yellow)

                Spacer()

                Image(systemName: "checkmark.square.fill")
            }.padding([.top, .bottom, .trailing], -7),
            alignment: .trailing)
        .padding()
)

Другие вопросы по тегам