Got a frustrating problem. I've created two separate views (and view models) for my app, one to use in portrait mode, the other to take advantage of the extra horizontal space in landscape. In both view models, I have a bool called usingClock.
@Published var usingClock: Bool = false
and in my view, I set the opacity of this clock depending on this bool...
Text(vm.isRunning ? vm.formatTime() : "0")
.font(.system(.title2, design: .monospaced))
.fontWeight(.black)
.frame(width: 90, height: 40)
.background(.thinMaterial)
.cornerRadius(20)
.overlay(RoundedRectangle(cornerRadius: 20)
.stroke(Color.gray, lineWidth: 2))
.opacity(vm.usingClock ? 1.00 : 0.00)
what is crazy is that in my portrait mode, this works. I change the setting of the bool, and the view automatically updates. but in the landscape mode, it doesn't work. I change the setting of the bool, and the view does not update. but if I simply re-orient the phone (simulator) to portrait and then back to landscape, now the view is correct. I can't for the life of me figure out why the exact same code works in portrait mode, regardless of me changing the orientation, and why in landscape mode it doesn't work until I rotate the phone.
I've even placed print statements showing that in my view model the bool turns false (say) and then in my view, it prints as true. Then simply reorient the phone, and now both print statements are false. Like what????
Any ideas why this is happening? This code is not that complicated.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi all, fairly new to SwiftUI, I'm following a sound manager class recipe, and it works fine if I just want to play one sound at a time, but now in the app I'm working on I need the sounds to overlap each other sometimes, and the singleton I'm using can't seem to do that. I'm not sure if it's the instance of the class, or the instance of the AVAudioPlayer that's the problem. Here is the code I'm using...
import Foundation
import AVKit
class SoundManager {
static let instance = SoundManager()
var player: AVAudioPlayer?
func playMySound() {
guard let url = Bundle.main.url(forResource: "mySound", withExtension: ".wav") else { return }
do {
player = try AVAudioPlayer(contentsOf: url)
player?.play()
} catch let error {
print("Error playing sound. \(error.localizedDescription)")
}
}
// each additional sound is another func like above.
I've poked around on SO and other places looking for better code examples, but nothing I have found works. Any help would be appreciated! Thanks!
Hi all, I have a picker populated by an enum... works just fine. Problem is when I try to localize my app, I get a compiler error in my picker that says "Instance method 'tag' requires that 'LocalizedStringKey' conform to 'Hashable'". I don't understand what this means. Here is my code:
localizable string file (excerpt)
//eng
"additionOnly" = "Addition Only";
"subtractionOnly" = "Subtraction Only";
"both" = "Both Addition and Subtraction";
// in VM:
enum MathMode: String, Hashable, CaseIterable {
case additionOnly = "additionOnly"
case subtractionOnly = "subtractionOnly"
case bothAdditionAndSubtraction = "both"
var localizedName: LocalizedStringKey { LocalizedStringKey(rawValue) }
}
@Published var selectedMode: String = UserDefaults.standard.string(forKey: "mathMode") ?? "Addition Only" {
didSet {
UserDefaults.standard.set(self.selectedMode, forKey: "mathMode")
print("portrait mode did set: \(selectedMode)")
}
}
//in View:
Menu {
Picker(selection: $settingsViewViewModel.selectedMode) {
ForEach(SettingsViewViewModel.MathMode.allCases, id: \.self) { mathMode in
Text(mathMode.localizedName)
.tag(mathMode.localizedName) //***
}
} label: {}
} label: {
Text(settingsViewViewModel.selectedMode)
.font(.title2)
}
.id(settingsViewViewModel.selectedMode)
*** this is the problem. if I use mathMode.rawValue... the code compiles, but in the picker I'm seeing "additionOnly" as my choice, rather than the value from the string file. If there's a better way to write all this, great, happy to change. Also, if I do away with the .tag altogether it still doesn't work. Thanks for your help.
I am really struggling to find how one creates a file that doesn't already exist in Objective-C, and then use that file write data. In C, one uses a fopen command, usually wrapped in an if statement to catch a failure...if ((file_pointer = fopen(file_name, "wb")) == NULL) { fprintf(stderr, "could not create file.\n"); exit(EXIT_FAILURE);}You have created a file, and you have a file_pointer to use as you write data to your file ... fprintf(file_pointer, %d, someInt); So easy.With Objective-C and Xcode... I'm already getting the feeling like there's many ways to skin a cat... but I can't get any of them to work for me.I see some people use an NSData method...BOOL written = [dataBuffer writeToFile:destinationPath options:0 error:NULL]; //assumes a NSData file *dataBuffer and NSString *destinationPath.But this doesn't work, no file is actually created.I also tried:NSFileHandle *file;NSData *data = [...file = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/filename.xyz"];[file writeData: data];But this also failed to create a file. There also seems to be a whole other trajectory using NSFileManager and a "createFileAtPath" method, which I ALSO could not get to work. HELP! What am I missing?