xmartlabs / Eureka

Elegant iOS form builder in Swift
https://eurekacommunity.github.io
MIT License
11.77k stars 1.33k forks source link

SegmentControl animates when changing userInterfaceStyle #2219

Open ashish-naik opened 2 years ago

ashish-naik commented 2 years ago

Describe the bug On selection of new segment, i change userInterfaceStyle in animated block. During this labels of the segmentControl, also animate. How to fix this?

Thanks.

To Reproduce

    <<< SegmentedRow<String>() {

            $0.title = "Select theme"
            $0.options = ["System", "Light", "Dark"]

            let currentInterfaceStyle = self.userDefaults.string(forKey: "currentUserInterfaceStyle")

            switch currentInterfaceStyle {
                case "light":
                    $0.value = "Light"
                case "dark":
                    $0.value = "Dark"
                default:
                    $0.value = "System"
            }

        }.cellSetup { cell, row in
            cell.textLabel?.textColor = Constants.ColorCompatibility.label
            cell.textLabel?.font = UIFont.boldSystemFont(ofSize: 14)
            cell.segmentedControl.selectedSegmentTintColor = Constants.ColorCompatibility.globalTintColor
        }.onChange({ (row) in

            let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first

                UIView.animate(withDuration: 0.4) {

                    switch row.value {

                        case "Dark":
                            window?.overrideUserInterfaceStyle = UIUserInterfaceStyle.dark
                            self.userDefaults.set("dark", forKey: "currentUserInterfaceStyle")

                        case "Light":
                            window?.overrideUserInterfaceStyle = UIUserInterfaceStyle.light
                            self.userDefaults.set("light", forKey: "currentUserInterfaceStyle")

                        case "System":
                            window?.overrideUserInterfaceStyle = UIUserInterfaceStyle.unspecified
                            self.userDefaults.set("system", forKey: "currentUserInterfaceStyle")

                        default:
                            window?.overrideUserInterfaceStyle = UIUserInterfaceStyle.unspecified
                            self.userDefaults.set("system", forKey: "currentUserInterfaceStyle")
                    }
                }
                self.userDefaults.synchronize()

        })

Expected behavior Segment control labels should not animate Screenshots If applicable, add screenshots to help explain your problem.

Versions (please complete the following information):

mats-claassen commented 2 years ago

Hi, I copied your code into one of the Eureka examples and it works just fine, no animations for the segmented control labels (Xcode 13.3, Simulator iPhone 13) I suggest you double check if there is anything else that might interfere with the animation or something else that animates.

ashish-naik commented 2 years ago

I am not animating anything in the view controller.

i tried animate block and change of userInterfaceStyle in switch row. it still affects UISegmentControl.

The form elements loads from left. Can this behaviour be altered? Could this be affecting UISegmentControl ?

I tried to add my code in the Eureka example code but getting below error. It may unrelated but i was earlier able to run example project. Below is initial part of the error.

Showing Recent Messages
Cycle inside Eureka; building could produce unreliable results. This usually can be resolved by moving the target's Headers build phase before Compile Sources.
Cycle details:
→ Target 'Eureka' has link command with output '/Users/a/Library/Developer/Xcode/DerivedData/Eureka-bsgphpazxmymhjcxmobqusednbco/Build/Products/Debug-iphoneos/Eureka.framework/Eureka'
○ Target 'Eureka' has compile command with input '/Users/a/Library/Developer/Xcode/DerivedData/Eureka-bsgphpazxmymhjcxmobqusednbco/Build/Intermediates.noindex/Eureka.build/Debug-iphoneos/Eureka.build/DerivedSources/Eureka_vers.c'
○ Target 'Eureka' has compile command for Swift source files
○ Target 'Eureka' has copy command from '/Users/a/Developer/sample iOS projects/Projects/Eureka-master/Source/Eureka.h' to '/Users/a/Library/Developer/Xcode/DerivedData/Eureka-bsgphpazxmymhjcxmobqusednbco/Build/Products/Debug-iphoneos/Eureka.framework/Headers/Eureka.h'
ashish-naik commented 2 years ago

When i present Preferences View controller in full screen, UISegmentControl works normally.

This worked in non full screen but don't get the animation to work. This is not an issue with Eureka though i am sure.

UIView.animate(withDuration: 0.5, animations: {

    self.overrideUserInterfaceStyle = newUserInterfaceStyle!

}) { (_) in
    window?.overrideUserInterfaceStyle = newUserInterfaceStyle!

}
mats-claassen commented 2 years ago

So this seems to be an issue with UISegmentedControl when in a view controller that is not full screen?

ashish-naik commented 2 years ago

Yes But this doesn't happen in example project.

Another issue i noticed is how the UISwitch changes colour first appearing as square. Don't know what is causing this strange behaviour. Please check the image above.

The form rows load from left. Can this behaviour be altered? They don't load like this in example project. Could this be affecting UISegmentControl ?

https://user-images.githubusercontent.com/4936420/167254630-fa5c3a87-e324-412c-ac99-b18c8d9f9959.mp4

ashish-naik commented 2 years ago

@mats-claassen Any suggestion or solution I can use?

mats-claassen commented 2 years ago

Sometimes such behaviour has to do with the moment you set up the form. Is that happening in viewDidLoad or later? Are you setting the whole form at once or are you building the viewController's form variable in multiple steps?

ashish-naik commented 2 years ago

it is in viewDidLoad and one form variable and multiple sections.

mats-claassen commented 2 years ago

Are you building the self.form variable gradually or assigning it at the end like this: (might be worth a try)

let form = Section()
    <<< TextRow()
    <<< IntRow()
self.form = form
ashish-naik commented 2 years ago

Thanks. This worked.

and found solution to prevent titles getting animated here by adding layoutIfNeeded() but UISwitch still becomes square during animation duration.