ios – Effectively Monitoring View and Display screen Sizes in SwiftUI Throughout Orientation Modifications

ios – Effectively Monitoring View and Display screen Sizes in SwiftUI Throughout Orientation Modifications


I have been engaged on a SwiftUI venture the place I wanted to dynamically monitor the dimensions of particular views and the complete machine display screen. One problem was making certain that the dimensions updates correctly when the machine orientation modifications with out breaking the format.

I created a reusable resolution utilizing GeometryReader and PreferenceKey. It captures each the subview measurement and the display screen measurement dynamically and could be utilized flexibly throughout totally different views. Beneath is the implementation.

I might love to listen to your ideas on this method or recommendations for additional optimization!

import Basis
import SwiftUI

// PreferenceKey to retailer and replace the dimensions worth
struct DimensionKey: PreferenceKey {
    static let defaultValue: CGSize = .zero
    
    static func scale back(worth: inout CGSize, nextValue: () -> CGSize) {
        worth = nextValue()
    }
}

// Extension on View for reusable measurement monitoring modifiers
extension View {
    // Modifier for monitoring the dimensions of a selected content material view
    func contentSizePreferenceModifier(measurement: @escaping (CGSize) -> Void) -> some View {
        self
            .background(
                GeometryReader { proxy in
                    Colour.clear
                        .choice(key: DimensionKey.self, worth: proxy.measurement)
                        .onPreferenceChange(DimensionKey.self, carry out: measurement)
                }
            )
    }
    
    // Modifier for monitoring the display screen measurement
    func screenSizePreferenceModifier(measurement: @escaping (CGSize) -> Void) -> some View {
        ZStack {
            GeometryReader { proxy in
                Colour.yellow.ignoresSafeArea()
                    .choice(key: DimensionKey.self, worth: proxy.measurement)
                    .onPreferenceChange(DimensionKey.self, carry out: measurement)
            }
            self
        }
    }
}

// The primary view to show the utilization of measurement monitoring
struct DataView: View {
    @State non-public var deviceSize: CGSize = .zero
    @State non-public var contentSize: CGSize = .zero
    
    var physique: some View {
        VStack {
            Textual content("Account Info")
                .font(.largeTitle)
            
            Group {
                Textual content("Display screen Width: (deviceSize.width, specifier: "%.2f")")
                Textual content("Display screen Peak: (deviceSize.peak, specifier: "%.2f")")
                    .padding(.backside)
            }
            .font(.title)
            
            VStack {
                Textual content("Content material Width: (contentSize.width, specifier: "%.2f")")
                Textual content("Content material Peak: (contentSize.peak, specifier: "%.2f")")
            }
            .font(.title)
            .foregroundStyle(.white)
            .background(Colour.purple)
            .contentSizePreferenceModifier { measurement in
                contentSize = measurement
            }
        }
        .screenSizePreferenceModifier { measurement in
            deviceSize = measurement
        }
    }
}

// Preview for SwiftUI
#Preview {
    DataView()
}

The rationale I used ZStack is that it does not have an effect on the format of the view the modifier is utilized to. It’s because GeometryReader sometimes takes up all accessible house, which may disrupt the unique format. By utilizing ZStack, the modifier solely tracks the dimensions with out interfering with the precise content material view.

Any recommendations for enhancements?

author avatar
roosho Senior Engineer (Technical Services)
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog. 
rooshohttps://www.roosho.com
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog. 

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here


Latest Articles

author avatar
roosho Senior Engineer (Technical Services)
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog.