How to get round shape images of the same size based on SF Symbols in SwiftUI?

Viewed 774

In my application I want to get simple round buttons based on SF Symbols of the same size. However, the same approach results in different image sizes depending on the symbol. For example, an image with a plus sign is larger than a minus sign.

To solve this problem, I use the ZStack trick in which I put a transparent plus under the minus. But I think this is not the best solution. Are there any better solutions?

HStack{
    
    Image(systemName: "plus")
        .padding()
                .overlay(
                    Circle()
                        .stroke(Color.primary,
                                lineWidth:1))
        
        
    Image(systemName: "minus")
        .padding()
                .overlay(
                    Circle()
                        .stroke(Color.primary,
                                lineWidth:1))
    //my solution
    ZStack {
      Image(systemName: "plus")
        .padding()
        .opacity(0.0)
        .overlay(
            Circle()
                .stroke(Color.primary,
                        lineWidth:1))
      Image(systemName: "minus")
    }
    
}

"minus" in the center has a smaller size than "plus", "minus" on the right - my solution:

"minus" in the center has a smaller size than "plus", "minus" on the right - my solution

2 Answers

use .circle


enter image description here

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        HStack {
            
            Image(systemName: "plus.circle")
                .resizable()
                .frame(width: 50, height: 50, alignment: .center)

            
            
            Image(systemName: "minus.circle")
                .resizable()
                .frame(width: 50, height: 50, alignment: .center)
            
        }

    }
}

You can use ViewModifier or if are buttons ButtonStyle

enter image description here

ViewModifier

    @available(iOS 13.0, *)
struct fillButtonCircle: ViewModifier {
    var foregroundColor: Color = .white
    var backgroundColor: Color = .green
    var dimension: CGFloat = 10
    func body(content: Content) -> some View {
        content
            .foregroundColor(foregroundColor)
            .padding(dimension)
            .background(backgroundColor)
            .clipShape(Circle())
            .frame(width: dimension, height: dimension)
            .overlay(
                Circle()
                    .stroke(Color.primary,
                            lineWidth:1))
    }
}

ButtonStyle

    @available(iOS 13.0, *)
struct CircleScaleButton: ButtonStyle {
    var color: Color = .blue
    var maxHeight: CGFloat = 35
    
    public func makeBody(configuration: Self.Configuration) -> some View {
        
            configuration.label
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: maxHeight, alignment: .center)
                .foregroundColor(.black)
                .background(RoundedRectangle(cornerRadius: 35/2.0).fill(self.color))
                .compositingGroup()
                .clipShape(Circle())
                .overlay(
                    Circle()
                        .stroke(Color.primary,
                                lineWidth:1))
                .opacity(configuration.isPressed ? 0.8 : 1.0)
                .scaleEffect(configuration.isPressed ? 0.9 : 1.0)
    }
}

Example

    struct SwiftUIViewTest: View {
    var body: some View {
       
                
        VStack {
            Text("Button")
            
            HStack {
                Button(action: {}, label: {
                    Image(systemName: "plus")
                })
                .buttonStyle(CircleScaleButton(color: .clear, maxHeight: 45))
                
                Button(action: {}, label: {
                    Image(systemName: "minus")
                })
                .buttonStyle(CircleScaleButton(color: .clear, maxHeight: 45))
            }
            
            Spacer()
                .frame(height: 50)
            
            Text("Image")
            HStack {
               
                Image(systemName: "plus")
                    .modifier(fillButtonCircle(foregroundColor: .black, backgroundColor: .clear, dimension: 40))
                               
                Image(systemName: "minus")
                    .modifier(fillButtonCircle(foregroundColor: .black, backgroundColor: .clear, dimension: 40))
            }
                   
        }
            
    }
}
Related