How to change PreferredStatusBarStyle programmatically - objective-c

I'd like to change the color of status bar from white to black by press button, programmatically only in a single-ViewController
This is the code:
- (UIStatusBarStyle)preferredStatusBarStyle {
NSLog(#"PreferredStatusBarStyle");
if(nav_bar.alpha==1)
{
NSLog(#"->UIStatusBarStyleBlackOpaque");
return UIStatusBarStyleBlackOpaque;
}
else
{
NSLog(#"->UIStatusBarStyleLightContent");
return UIStatusBarStyleLightContent;
}}
then When I press a button action is:
[self setNeedsStatusBarAppearanceUpdate];
But this doesn't work!
When I press the button log write the correct status according to navbar.alpha, but statusbar text color remain UIStatusBarStyleBlackOpaque like when view appear.

setStatusBarStyle:animated: has been deprecated. In iOS9 you can achieve the same thing using preferredStatusBarStyle and setNeedsStatusBarAppearanceUpdate.
In your View Controller:
override func preferredStatusBarStyle() -> UIStatusBarStyle {
if (condition) {
return .LightContent
}
return .Default
}
And then when your condition changes:
self.setNeedsStatusBarAppearanceUpdate()

On Swift 4:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Hope it helps anybody else to find this post.

what you need to do, is to call the -setStatusBarStyle:animated: method thru the shared application, like this
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
you can use it without the animated parameter as well. keep in mind that UIStatusBarStyleBlackOpaque is deprecated in iOS 7, documentation says you wanna use UIStatusBarStyleLightContent instead
edit:
sorry, if u wanna use preferredStatusBarStyle, take a look at this preferredStatusBarStyle isn't called

Related

SwiftUI: Is it possible to turn off predictive text for a TextField

I would like to turn off predictive text/autocorrect for a TextField in SwiftUI. Looks like this was possible in with UITextField:
Disable UITextField Predictive Text
I checked the Apple documentation for TextField and googled, but can't find anything about this.
Has anyone found a way to disable the predictive text/autocomplete for a TextField?
Thank you!
Seems like it is now possible using Xcode 11 Beta 5. There is a new modifier to disable the autocorrection on TextField
func disableAutocorrection(_ disable: Bool?) -> some View
https://developer.apple.com/documentation/swiftui/textfield/3367734-disableautocorrection?changes=latest_beta
Edit:
Modifier disableAutocorrection is deprecated in iOS 16.1. The new modifier is autocorrectionDisabled:
func autocorrectionDisabled(_ disable: Bool = true) -> some View
https://developer.apple.com/documentation/swiftui/presentedwindowcontent/autocorrectiondisabled(_:)?changes=latest_beta&language=_5
This should work:
.disableAutocorrection(true)
Turns out you need to set the keyboard type to .alphabet for .disableAutocorrection(true) to work.
here is the extension I use:
extension View {
func removePredictiveSuggestions() -> some View {
self.keyboardType(.alphabet)
.disableAutocorrection(true)
}
}
Xcode 12.3 Swift 5.3
If you need to disable autocorrection on multiple TextFields, or indeed add other modifiers, then create a custom TextField:
struct TextFieldCustom: View {
let title: String
let text: Binding<String>
init(_ title: String, text: Binding<String>) {
self.title = title
self.text = text
}
var body: some View {
TextField(title, text: text)
.disableAutocorrection(true)
// add any other modifiers that you want
}
}
Example Usage:
Form {
Section(header: Text("Details")) {
TextFieldCustom("Field1", text: $field1)
TextFieldCustom("Feild2", text: $field2)
TextFieldCustom("Field3", text: $field3)
}
}
For the iOS 16.2 SDK, I needed to do this:
.keyboardType(.alphabet)
.textContentType(.oneTimeCode)
.autocorrectionDisabled(true)
(oneTimePasscode is an old UIKit hack to achieve the same result. It feels dirty to me, and I wouldn't be surprised if this behaviour changes again in the future...)

tvOS UICollectionView get currently focused item's index path

So this is kind of a noobish question but I just can't figure out a very simple way to detect currently focused item's indexPath.
I looked around hoping to see something very easy like collectionView.indexPathOfCurrentlyFocusedItem but didn't find anything remotely close.
So I digged around and tried to find something similar at UIFocusEnvironment, UIFocusUpdateContext trying to find the desired property but failed.
So, the only solution I can come up with is just iterating through all visible cells and finding a cell with focused property set to true.
So is there a more simple and elegant way to find the currently focused item's indexPath? (Except tracking it through delegate method and saving it in view controller's property)
You can use UIScreen property focusedView as followed for this:
if let focusedCell = UIScreen.main.focusedView as? UICollectionViewCell {
if let indexPath = collectionView.indexPath(for: focusedCell) {
print("IndexPath is \(indexPath)")
}
}
Use didUpdateFocusInContect - UICollectionViewDelegate
func collectionView(collectionView: UICollectionView, didUpdateFocusInContext context: UICollectionViewFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
if collectionView == self.collectionView {
print(context.nextFocusedIndexPath)
}
}
This wil return the indexPath of the cell that is going to be focused, you could also try:
context.previouslyFocusedIndexPath
Depends what you're trying to do.
So, your target is to do something when you get and lose focus particularly on a cell under tvOS. The catch is you're moving around other UI elements, and therefore the context could be different. You have to change in this context only those UIs that you have to care of.
The right place to make your implementation is func didUpdateFocusInContext(), like this:
override func didUpdateFocusInContext(
context: UIFocusUpdateContext,
withAnimationCoordinator coordinator: UIFocusAnimationCoordinator
) {
coordinator.addCoordinatedAnimations({
if let cell = context.previouslyFocusedView as? UICollectionViewCell {
cell.layer.borderWidth = 2
}
if let cell = context.nextFocusedView as? UICollectionViewCell {
cell.layer.borderWidth = 5
}
},
completion: nil)
}
Now we're using the focus coordinator to apply our logic:
When the previously focused item is UICollectionViewCell then you have to release the focus to the next item. You shouldn't care what is the next item because it could be a collection cell or not. For fun, in this case, let's change the border to 2. This value could be set by default.
When the next focused item is UICollectionViewCell then you've to handle it is a similar way, or it will become a mess... So, let's change the border to 5.
As you can see, didUpdateFocusInContext() provides a generic approach for all views within your current visual context. You can apply the same approach for other UI elements.
Have a fun with tvOS...
Here's how I accomplished this in shouldUpdateFocusInContext
Solution
override func shouldUpdateFocusInContext(context: UIFocusUpdateContext) -> Bool {
// The magic is in the next two lines
let cell: UICollectionViewCell = context.nextFocusedView as! UICollectionViewCell
let indexPath: NSIndexPath? = self.collectionView.indexPathForCell(cell)
print(indexPath)
// <NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0}
return true
}

Xcode BOOL type: from input YES, I want to get value NO

I have a very simple method, but it does not work. Ultimately, from input YES, I want to get NO and reverse.
-(void)myMethod:(BOOL)ys{
if (ys==YES) {
myLabel.hidden=NO;
myButton.hidden=NO;
}{
myLabel.hidden=YES;
myButton.hidden=YES;
}
}
Can you guys help me to correct and shorten the code? Thanks
Maybe this is a litle easier:
-(void)myMethod:(BOOL)ys{
myLabel.hidden = !ys;
myButton.hidden = !ys;
}
-(void)myMethod:(BOOL)visible
{
[myLabel setHidden:!visible];
[myButton setHidden:!visible];
}
The code should be working. However, your code is not working is probably because you did not set the referencing outlets for your label and button (If you created them with interface builder).
Referencing outlets should be set like this. Otherwise, the complier would not know if the button you want to hide is the button on the interface.
If you created the button/label with codes, check if you have them released before you are trying to set them visible or not please.
-(void)myMethod:(BOOL)ys{
if (ys) {
myLabel.hidden=NO;
myButton.hidden=NO;
} else {
myLabel.hidden=YES;
myButton.hidden=YES;
}
}
If we are trying to make it short...`
-(void)myMethod:(BOOL)ys{
myLabel.hidden = myButton.hidden = !ys;
}

Implementing "Show in Finder" button in Objective-C

In my application I would like to create a 'Show in Finder' button.
I have been able to figure out how to pop up a Finder window of that directory but haven't figured out how to highlight the file like the OS does.
Is this possible?
NSArray *fileURLs = [NSArray arrayWithObjects:fileURL1, /* ... */ nil];
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:fileURLs];
stolen from
Launch OSX Finder window with specific files selected
You can use NSWorkspace method -selectFile:inFileViewerRootedAtPath: like this:
[[NSWorkspace sharedWorkspace] selectFile:fullPathString inFileViewerRootedAtPath:pathString];
Its worth mentioning that owen's method only works from osx 10.6 or later (Ref: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSWorkspace_Class/Reference/Reference.html ).
So if your writing something to run on the older generations its probably better to do it in the way suggested by justin as its not been deprecated (yet).
// Place the following code within your Document subclass
// enable or disable the menu item called "Show in Finder"
override func validateUserInterfaceItem(anItem: NSValidatedUserInterfaceItem) -> Bool {
if anItem.action() == #selector(showInFinder) {
return self.fileURL?.path != nil;
} else {
return super.validateUserInterfaceItem(anItem)
}
}
// action for the "Show in Finder" menu item, etc.
#IBAction func showInFinder(sender: AnyObject) {
func showError() {
let alert = NSAlert()
alert.messageText = "Error"
alert.informativeText = "Sorry, the document couldn't be shown in the Finder."
alert.runModal()
}
// if the path isn't known, then show an error
let path = self.fileURL?.path
guard path != nil else {
showError()
return
}
// try to select the file in the Finder
let workspace = NSWorkspace.sharedWorkspace()
let selected = workspace.selectFile(path!, inFileViewerRootedAtPath: "")
if !selected {
showError()
}
}

Cocoa:Testing for the same object with ifs/switches

Ok so here's my code, it works great:
- (void)textViewDidChange:(UITextView *)textView{
if (textView==someObject) {
[detailItem setValue:textView.text forKey:#"someObjectAttribute"];
}
The problem is that I have lots of textviews instances to test for and I would prefer to find some other way to consolidate the code. I was thinking of something like a switch but I don't see how that would work. Any ideas?
One way would be to use the integer tag of each view. In your code, you’d have an enum like:
enum
{
kThingView,
kOtherView,
...
};
Each view's tag is set appropriately in IB or when setting up the view programatically. Then:
- (void) textViewDidChange:(UITextView *)textView
{
switch (textView.tag)
{
case kThingView:
...
}
}