I am using Swift3 and have the following variable str8redpickteamreminder which is either 1 or 0. I also have a switch called whichthe code can can be seen at the bottom of the question.
I thought I could use the following code which would change the visuals of the switch:
if str8redpickteamreminder == 1 {
self.teamSelectNotif = true
}
else {
self.teamSelectNotif = false
}
Yet the switches just stay as on when the code is run. How can I make the switch linked to teamSelectNotif show as false in the app programatically?
Any help is appreciated.
Switch Code:
#IBAction func `switch`(_ sender: UISwitch) {
if sender.isOn == true {
switch sender.tag {
case 1:
teamSelectNotif = true
print(toggleUpdate(toggle: "str8redpickteamreminder", setting: 1))
case 3:
resultsNotif = true
print(toggleUpdate(toggle: "str8redresults", setting: 1))
default:
break
}}
else if sender.isOn == false {
switch sender.tag {
case 1:
teamSelectNotif = false
case 3:
resultsNotif = false
default:
break
}}
}
Related
On iOS app with GoogleInteractiveMediaAds integrated "Skip Ad" button doesn't work. Meanwhile manual call adsManager.skip() works perfectly. The button itself reacts to the tuches because it changes bounds and seems highlighted. Unfortunately, I haven't found anything according to handle tap manually, so maybe somebody has already been in this situation and could help with it.
guard
let adInformation = delegate?.latestAdInformation(), let url = adInformation.urlForIMA,
let adContainer = delegate?.videoAdDisplayContainerView()
else { return }
switch adInformation.adsType {
case .interstitials, .none:
self.play(ignoreAds: true)
return
case .prerolls, .all:
fallthrough
#unknown default:
break
}
let adDisplayContainer = IMAAdDisplayContainer(adContainer: adContainer, companionSlots: nil)
let request = IMAAdsRequest(
adTagUrl: url,
adDisplayContainer: adDisplayContainer,
contentPlayhead: contentPlayhead,
userContext: nil)
adsLoader.requestAds(with: request)
func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) {
// Grab the instance of the IMAAdsManager and set ourselves as the delegate
adsManager = adsLoadedData.adsManager
adsManager?.delegate = self
// Create ads rendering settings and tell the SDK to use the in-app browser.
let adsRenderingSettings = IMAAdsRenderingSettings()
if let vc = delegate?.adWebControllerPreferredOpenViewController() {
adsRenderingSettings.webOpenerPresentingController = vc
}
// Initialize the ads manager.
adsManager?.initialize(with: adsRenderingSettings)
}
func adsLoader(_ loader: IMAAdsLoader!, failedWith adErrorData: IMAAdLoadingErrorData!) {
self.play(ignoreAds: true)
}
func adsManager(_ adsManager: IMAAdsManager!, didReceive event: IMAAdEvent!) {
if event.type == IMAAdEventType.LOADED {
adsManager.start()
}
}
func adsManager(_ adsManager: IMAAdsManager!, didReceive error: IMAAdError!) {
self.play(ignoreAds: true)
}
func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager!) {
self.pause(ignoreAds: true)
}
func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager!) {
self.play(ignoreAds: true)
}
I am trying to hide a button, until another condition is met. When i load the app i am using the slider and when it reaches the max, it should make the button visible, but for some weird reason it won't. I have just done it in another app with no issues and the code is almost identical.?
Can't figure out what to do tbh.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
profileVisible.isHidden = true
}
#IBAction func btnClicked(_ sender: Any) {
motionManager.startDeviceMotionUpdates(to: queue) { (motion, error) in DispatchQueue.main.async {
self.slider.value = Float((motion?.attitude.roll ?? 0 ) * 1.4)
print(self.slider.value)
if self.slider.value == 1.0 {
self.profileVisible = false
self.motionManager.stopDeviceMotionUpdates()
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); // vibrates when payment has succeded
}
if self.slider.value == -1.0 {
profileVisible = true
self.motionManager.stopDeviceMotionUpdates()
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
}
}
}
You miss setting here
if self.slider.value == 1.0 {
self.profileVisible = false
And here
if self.slider.value == -1.0 {
profileVisible = true
Should be
profileVisible.isHidden = true/false // set it's value according to your logic
profileVisible is of type UIButton you need to set it's isHidden property not it directly
This question already has an answer here:
Swift 4 save from the background color that was consulted in the App
(1 answer)
Closed 4 years ago.
I've got 4 SwichButton, this is standard to Off.
How can I save the setting when a switch button is set to on ?
I have this:
#IBAction func SwitchNofic(_ sender: UISwitch) {
let switchTag = sender.tag
if (switchTag == 1) && (sender.isOn == true){
print("1")
createNoficationMorgen()
}else if (switchTag == 2) && (sender.isOn == true){
print("2")
createNoficationMittag()
}else if (switchTag == 3) && (sender.isOn == true){
print("3")
createNoficationAbend()
}else if (switchTag == 4) && (sender.isOn == true){
print("4")
createNoficationNacht()
}
}
It depends if you want to save it just for the time the app is alive.
Just use a boolean variable so you know what is on and what is not, also each switchButton has a property isOn.
If you want it to be persistant try UserDefaults.
Swift 4
To save permanently :
UserDefaults.standard.set(true, forKey: “isDarkModeKey”)
To retrieve (this should be called in viewDidAppear):
let isDarkModeEnabled = UserDefaults.standard.bool(forKey: “isDarkModeKey”)
if isDarkModeEnabled {
mySwicth.setOn(true, animated : false)
//set the background to dark
} else {
mySwicth.setOn(false, animated : false)
//set the background to white
}
Alamofire.request("https://example.com/writecomment.php", method: .post, parameters: parameters).validate().responseJSON { response in
switch response.result {
case .success:
if let json = response.result.value {
var success = 0
if let dictJSON = json as? [String: AnyObject] {
if let successInteger = dictJSON["success"] as? Int {
success = successInteger
if success == 1
{
//succes
}
}
}
}
case .failure(_):
return
}
}
This is connected to an UIButton action
It SOMETIMES triggers service calls multiple times when user tap button.
How to prevent multiple calls?
Example::
var isAPICalling = false
#IBAction func btnTapped(_ sender: UIButton) {
if isAPICalling == false
{
isAPICalling = true
self.APICalling() // Your API calling method
}
}
In APICalling() method set isAPICalling = false when you get response.
OTHER OPTION :
Use ActivityIndicator when you request that time start indicator and after response stop indicator. So you cannot able to tap on button.
You can do one thing without using flag, if you have button outlet then just make button state selected when button click action is performed.
then call API and once you get the response make button state normal. so it will call only once when user click on button.
#IBAction func btnApiAction(_ sender: Any) {
if btnAPI.isSelected == false {
btnAPI.isSelected = true
//Call API here
}else {
//Do nothing here
}
}
if API Call is get failed or if you are getting any error then also change button state to normal so user can click again on button.
Disable UIButton when you call API. And enable back when api call finished.
#IBAction func didTapButton(_ sender: UIButton) {
sender.isEnabled = false
Alamofire.request(/* Params */) { response in
sender.isEnabled = true
// parse response - response.result
}
}
I prefer to add ActivityIndicatorView to the button view, and remove when finished for better UX.
I have a split view controller with the top view controller set to a table view controller that is to display a list of playlists for selection. The first time the app is loaded it asks for music access permission. Answering yes does give it permission but the table view displays no playlists. I end up having to kill the app and run it again. Am I asking for music library permission the wrong place? It is in that top view controller's viewWillAppear and store the playlists I'm using (since some are screened out) in a class of playlists.
override func viewWillAppear(_ animated: Bool) {
self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
super.viewWillAppear(animated)
checkMediaAccessAndSetup()
}
func checkMediaAccessAndSetup() {
let authorizationStatus = MPMediaLibrary.authorizationStatus()
switch authorizationStatus {
case .notDetermined:
// Show the permission prompt.
MPMediaLibrary.requestAuthorization({[weak self] (newAuthorizationStatus: MPMediaLibraryAuthorizationStatus) in
// Try again after the prompt is dismissed.
self?.checkMediaAccessAndSetup()
})
case .denied, .restricted:
// Do not use MPMediaQuery.
return
default:
// Proceed as usual.
break
}
// Do stuff with MPMediaQuery
self.setupPlaylistStore()
tableView.reloadData()
}
The chief problems with your code are
You are completely failing to grapple with the fact that the requestAuthorization completion function is called on a background thread. You need to step out to the main thread to do work on the interface.
You have omitted the all-important .authorized case. When you have work to do that depends upon your authorization status, you must do it now if you are authorized, but after authorization if you are not determined.
Thus, this is the correct scheme for a coherent authorization check (where f() is the thing you always want to do if you can):
let status = MPMediaLibrary.authorizationStatus()
switch status {
case .authorized:
f()
case .notDetermined:
MPMediaLibrary.requestAuthorization() { status in
if status == .authorized {
DispatchQueue.main.async {
f()
}
}
}
// ...
}
If you abstract this code into a utility method, where f can be anything, you can do this everywhere in your app where authorization might be necessary — not merely at startup.
Thanks for the comments, it gave me clues of the multi-threading that was going on and I was able to fix it with a timer call if there were no playlists in the class to keep on checking and reload the table data.
override func viewWillAppear(_ animated: Bool) {
self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
super.viewWillAppear(animated)
checkMediaAccess()
self.setupPlaylistStore()
tableView.reloadData()
if store.allPlaylists.count < 1 {
playlistTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.playlistTimerCall), userInfo: nil, repeats: true)
}
}
#objc func playlistTimerCall() {
self.setupPlaylistStore()
if store.allPlaylists.count > 1 {
tableView.reloadData()
playlistTimer?.invalidate()
}
}
func checkMediaAccess() {
let authorizationStatus = MPMediaLibrary.authorizationStatus()
switch authorizationStatus {
case .notDetermined:
// Show the permission prompt.
MPMediaLibrary.requestAuthorization({[weak self] (newAuthorizationStatus: MPMediaLibraryAuthorizationStatus) in
// Try again after the prompt is dismissed.
self?.checkMediaAccess()
})
case .denied, .restricted:
// Do not use MPMediaQuery.
return
default:
// Proceed as usual.
break
}
}
func setupPlaylistStore() {
// purge store
store.clearAllPlaylists()
// create a query of media items in playlist
let myPlayListsQuery = MPMediaQuery.playlists()
if myPlayListsQuery.collections != nil {
playlists = myPlayListsQuery.collections!
}
// add playlists to MyPlaylist(s)
if playlists.count > 0 {
for index in 0...playlists.count - 1 {
let playlist = playlists[index]
store.addPlaylist(playlist: playlist as! MPMediaPlaylist)
}
}
var toBeRemoved = [Int]()
let defaults = UserDefaults.standard
if defaults.bool(forKey: "exclude_smart_playlists") {
//smart
for index in 0...(playlists.count - 1) {
let playlist = playlists[index]
let theAttributes = playlist.value(forProperty: MPMediaPlaylistPropertyPlaylistAttributes) as! Int
if theAttributes == 2 {
toBeRemoved.append(index)
}
}
}
if defaults.bool(forKey: "exclude_folders") {
//folders
for index in 0...(playlists.count - 1) {
let playlist = playlists[index]
let isFolder = playlist.value(forProperty: "isFolder")
let stringIsFolder = String("\(String(describing: isFolder))")
if ((stringIsFolder.range(of: "1")) != nil) {
toBeRemoved.append(index)
}
}
}
//sort from the last to the first so i don't reindex
let reverseSortedPlaylists = toBeRemoved.sorted(by: >)
// remove the unwanted playlists
for list in reverseSortedPlaylists {
store.removePlaylist(index: list)
}
}