4

I have my code as follows:

Rectangle()
    .fill(Color.red)
    .frame(width: 60, height: 60, alignment: .center)
    .cornerRadius(recording ? 5 : 30)

So I was wondering if .frame could be conditional just like .cornerRadius is. I am doing that in order to morph the shape, however I also need to make it smaller when it morphs. An example is a Voice Memos app's record button.

4 Answers 4

11

If you're talking about using no frame modifier altogether (or providing a clean way to do different frames), a ViewModifier might be a good option:

struct ContentView: View {
    @State private var recording = false
    
    var body: some View {
        Rectangle()
            .fill(Color.red)
            .modifier(CustomFrameModifier(active: recording))
            .cornerRadius(recording ? 5 : 30)
    }
}

struct CustomFrameModifier : ViewModifier {
    var active : Bool
    
    @ViewBuilder func body(content: Content) -> some View {
        if active {
            content.frame(width: 60, height: 60, alignment: .center)
        } else {
            content
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Oh, well. This is actually a lot cleaner. Thank you so much!
Such a clever and creative solution! I think this is the best approach because it gives you the flexibility of having no dimension to pass too. Can easily be extended to take parameters for the ternary expression so it can have one of three states essentially: value a, b and nil.
4

Yes, you can use the ternary conditional statement with .frame as well.

Example:

.frame(width: recording ? 40 : 60, height: recording ? 40 : 60, alignment: .center)

1 Comment

Thanks, apparently my error when I was doing that was not using self.recording
1

I assume you wanted something like this

enter image description here

        Rectangle()
            .fill(Color.red)
            .frame(width: recording ? 45 : 60, height: recording ? 30 : 60, alignment: .center)
            .cornerRadius(recording ? 5 : 30)
            .onTapGesture {
                recording.toggle()
            }
            .animation(.default, value: recording)

Comments

0

You can do with ?


enter image description here

import SwiftUI

struct ContentView: View {
    
    @State private var recording: Bool = Bool()
    @State private var color: Color = Color.blue
    
    var body: some View {
        
        ZStack {
            
            Circle()
                .fill(Color.white)
                .frame(width: 60.0, height: 60.0, alignment: .center)
                .shadow(radius: 10.0)
            
            Circle()
                .fill(color)
                .frame(width: recording ? 30.0 : 60.0, height: recording ? 30.0 : 60.0, alignment: .center)  // <<: Here!

 
        }
        .onTapGesture { recording.toggle() }
        .animation(.easeInOut, value: recording)
        .onChange(of: recording) { newValue in if newValue { colorFunction() } else { color = Color.blue } }

    }
    
    
    func colorFunction() {

        if (color != Color.red) { color = Color.red } else { color = Color.clear }
        
        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) { if recording { colorFunction() } }
        
    }
    
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.