2

I am writing a swiftUI app for macOS.

Consider this situation: I have a scroll view containing an image that is resizable. If I resize the window to smaller than the image, the scroll views bars appear as expected. If I use .scaleEffect(someStateVar) to resize the image (by changing someStateVar), the scroll view content does not update to the new size of the image.

Other than wrapping NSScrollView into a swiftUI view, how do I indicate to the swiftUI scrollview that the content size has changed?

Example that shows scaling the image does not set the "content size" of the scrollview. When you size the clock to large than the scroll view, the scroll bars do not appear and you cannot scroll. When you try to scroll, you briefly see the hidden areas but the view jumps back to the original location.

import SwiftUI

struct MyImageView: View {
    
    @State var scale: CGFloat = 1
    
    var theImage: some View{
        ScrollView([.horizontal, .vertical]){
            VStack{
                HStack{
                    Image(systemName: "clock.fill")
                        .scaleEffect(scale)
                }
            }
        }
    }
    
    var body: some View {
        theImage
        Slider(value: $scale, in: 1...1000)
    }
}

struct ContentView: View {
    var body: some View {
        MyImageView()
    }
}
2
  • 1
    You can provide an explicit frame to the VStack with the .frame modifier. The downside is you have to know the dimensions to send to that modifier. Commented Aug 23, 2021 at 3:00
  • @jnpdx Submit this an as answer and Ill except it. FYI The image size is calculated in the real code, so setting the VStack frame was a very simple and working fix. Thanks for the time, I appreciate it! Commented Aug 23, 2021 at 3:54

1 Answer 1

1

You can use the .frame modifier to explicitly set the size of the VStack. The downside is that you have to know the full dimensions.

var theImage: some View{
    ScrollView([.horizontal, .vertical]){
        VStack{
            HStack{
                Image(systemName: "clock.fill")
                    .scaleEffect(scale)
            }
        }
        .frame(width: 50 * scale, height: 50 * scale, alignment: .center)
    }
}
Sign up to request clarification or add additional context in comments.

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.