【问题标题】:Edited: How we can alignment Image with Images and Text withTexts in SwiftUI, Multi-alignment?编辑:我们如何在 SwiftUI 中将图像与图像和文本与文本对齐,多对齐?
【发布时间】:2021-01-24 11:02:35
【问题描述】:

我有一个 VStack,它有一些 HStack,正如你在我的代码中看到的那样,在我的每个 Hstack 里面都有一个图像和文本,在运行我的代码之后,所有代码的 Alignmet 都很难看,我希望图像对齐中心在一起并且文本对齐领先。我该如何解决这个问题? 我可以使所有 Image .center 对齐,以及所有 Text .leading 对齐。但我不能让两者同时发生。

struct CustomAlignment: AlignmentID
{
    static func defaultValue(in context: ViewDimensions) -> CGFloat
    {
        return context[HorizontalAlignment.center]
    }
}


struct CustomAlignment2: AlignmentID
{
    static func defaultValue(in context: ViewDimensions) -> CGFloat
    {
        return context[HorizontalAlignment.leading]
    }
}



extension HorizontalAlignment
{
    static let custom: HorizontalAlignment = HorizontalAlignment(CustomAlignment.self)
    static let custom2: HorizontalAlignment = HorizontalAlignment(CustomAlignment2.self)
}




import SwiftUI

struct ContentView: View {
    var body: some View {
    
    

    
    
    VStack(alignment: .custom)
    {
        

        HStack()
        {
            Image(systemName: "folder")
                .alignmentGuide(.custom) { $0[HorizontalAlignment.center] }
            Text("Some texts here.")
                .alignmentGuide(.custom2) { $0[HorizontalAlignment.leading] }
            Spacer()
        }
            


        HStack()
        {
            Image(systemName: "music.note")
                .alignmentGuide(.custom) { $0[HorizontalAlignment.center] }
            Text("Some texts here.")
                .alignmentGuide(.custom2) { $0[HorizontalAlignment.leading] }
            Spacer()
        }
      


        HStack()
        {
            Image(systemName: "person.fill.questionmark")
                .alignmentGuide(.custom) { $0[HorizontalAlignment.center] }
            Text("Some texts here.")
                .alignmentGuide(.custom2) { $0[HorizontalAlignment.leading] }
            Spacer()
        }
     
        
        
    }
    .padding()
    
    
    
    Spacer()
    
    
    
}

}

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    如果您想要精确控制,请使用自定义对齐指南。

    关于您对使用固定框架的评论,here 是一篇解释框架如何在 SwiftUI 中工作的文章。 基本上,在这种情况下,框架修饰符只是在 SF 周围添加一个固定大小的框架,但不会改变固有大小。

    struct ContentView: View {
        var body: some View {
            VStack(alignment: .sfView) {
                SFView(title: "This is some text", image: "folder")
                SFView(title: "SwiftUI is cool. Combine is cooler.", image: "snow")
                SFView(title: "This is a music note. This has a different length.", image: "music.note")
            }
        }
    }
    
    private struct SFView: View {
        let title: String
        let image: String
        var body: some View {
            HStack(spacing: 8) {
                Image(systemName: image)
                    .font(.system(size: 20))
                    .frame(width: 32, height: 32)
                    .alignmentGuide(.sfView) { d in d[HorizontalAlignment.center] }
                Text(title)
                    .alignmentGuide(.sfView) { d in d[HorizontalAlignment.leading] }
            }
        }
    }
    
    private extension HorizontalAlignment {
        struct SFViewAlignment: AlignmentID {
            static func defaultValue(in d: ViewDimensions) -> CGFloat {
                d[HorizontalAlignment.leading]
            }
        }
        static let sfView = HorizontalAlignment(SFViewAlignment.self)
    }
    

    【讨论】:

    • 谢谢,你用 .leading 表示 Text,我们如何在不使用 frame 的情况下用 .center 表示 Image?
    • 您可以将图像对齐方式更改为 .center 请注意,SwiftUI 中的框架是不同的。在这种情况下,它们不会改变 SF 的大小,而只是在其周围添加一个框架。
    • 只使用Label怎么样?
    【解决方案2】:

    您必须为图像添加一个框架,因为某些 SF 符号比其他符号大,同时尝试创建可重复使用的视图。

    试试这样的:

    struct ContentView: View {
        var body: some View {
            VStack {
                RowView(title: "Some texts here.", image: "folder")
                
                RowView(title: "Some texts here.", image: "person.fill.questionmark")
                
                RowView(title: "Some texts here.", image: "snow")
                
                RowView(title: "Some texts here.", image: "forward.end.alt.fill")
            }
            .padding()
            
            Spacer()
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    
    struct RowView: View {
        let title: String
        let image: String
        
        var body: some View {
            // Option 1 with Label
    //        Label(
    //            title: {
    //                Text(title)
    //            },
    //            icon: {
    //                Image(systemName: image)
    //                    .frame(width: 30, height: 30)
    //            }
    //        )
            // Option 2 with HStack
            HStack {
                Image(systemName: image)
                    .frame(width: 30, height: 30)
                Text(title)
                Spacer()
            }
        }
    }
    

    【讨论】:

    • 谢谢,但这不是我要求的,我需要修复对齐,Apple 不建议更改 SF 大小
    【解决方案3】:

    你太复杂了。对于这么简单的事情,您不需要使用所有这些自定义对齐和约束。

    回到基础并使用常规的 VStack / HStack 并将图标设置为精确的框架。问题的出现是因为图标的宽度略有不同。

    struct TestView: View {
        var body: some View {
    
            VStack(alignment: .leading) {
                HStack {
                    Image(systemName: "folder")
                        .frame(width: 30, height: 30, alignment: .center)
                    Text("Some text here")
                }
                
                HStack {
                    Image(systemName: "person.fill.questionmark")
                        .frame(width: 30, height: 30, alignment: .center)
    
                    Text("Some text here")
                }
                
                HStack {
                    Image(systemName: "snow")
                        .frame(width: 30, height: 30, alignment: .center)
    
                    Text("Some text here")
                }
                
                HStack {
                    Image(systemName: "music.note")
                        .frame(width: 30, height: 30, alignment: .center)
    
                    Text("Some text here")
                }
            }
        }
    }
    

    【讨论】:

    • 谢谢,我已经解决了仅使用对齐的问题,但是在 Foreach 中出现问题,然后我使用 .frame(width: 20) 作为图像。我认为这个问题有更好的解决方法。如果您已经在 SwiftUI 中使用过 List,List 会自动对齐我尝试的那些细线。
    猜你喜欢
    • 2011-01-14
    • 2012-09-29
    • 2014-10-06
    • 1970-01-01
    • 2016-06-19
    • 2023-03-14
    • 1970-01-01
    相关资源
    最近更新 更多