2

我有一个视图,我想在它的右上角和右下角添加两个图标。我设法做到了:

图片

我使用了两个 ZStack:

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 中心。我可能可以通过更改偏移量来解决这个问题,但这会使代码更加笨拙。

有没有更简单的方法?

4

2 回答 2

1

您可以使用overlay修饰符,如下所示:

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 的建议来使用 a 对齐符号中心VStack。然后我们可以将这两个offset修饰符分解paddingVStack.

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()
)

与之前的图像相同,但现在星形和复选标记水平对齐

于 2021-08-17T21:41:26.143 回答
0

仅使用一个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)

在此处输入图像描述

于 2021-08-18T11:28:24.153 回答