SwiftUI: How to get window in Objective-C - objective-c

let scene = UIApplication.shared.connectedScenes.first
if let sd: SceneDelegate = (scene?.delegate as? SceneDelegate) {
let window = sd.window
}
this is in Swift, I want to convert this into Objective-C. I have tried this:
UIScene *scene = [[[[UIApplication sharedApplication]connectedScenes]allObjects]firstObject];
but now there is no SceneDelegate; in Objective-C there is UIKit's UIWindowSceneDelegate.
also I wasn't able to access UIScenedelegate. Scenedelegate is in Swift and I am trying to get window in objective-c
but now I'm not able to access window in swiftUI.

Check scene.delegate to make sure it conforms to the protocol, then cast the protocol on it so the compiler will let you use the protocol properties and/or methods.
UIScene *scene = [[[[UIApplication sharedApplication] connectedScenes] allObjects] firstObject];
if([scene.delegate conformsToProtocol:#protocol(UIWindowSceneDelegate)]){
UIWindow *window = [(id <UIWindowSceneDelegate>)scene.delegate window];
}

Related

Objective-C type downcasting

I am trying to override
- (void)makeWindowControllers;
Here is the code for it:
NSStoryboard* const storyboard = [NSStoryboard storyboardWithName:#"Main" bundle:nil];
NSWindowController* const windowController = [storyboard instantiateControllerWithIdentifier:#"Document Window Controller"];
And then I would like to add an image to ViewController that user has selected through open... in Swift I would simply do:
(windowController.contentViewController as? ViewController)?.imageView?.image = openedImage
How I could do this downcasting in Objective-C? I really got confused since I haven't done much type converting while I was learning C. Thanks.
[[((ViewController *)[windowController contentViewController]) imageView] setImage: openedImage];

Can I attach an NSTouchBar to an NSWindow after it's been created with no specific NSTouchBar support?

I'm using SDL to create a window for use with OpenGL and the only information it gives back is the NSWindow object.
Can I use that to then subsequently associate an NSTouchBar with that window?
I've successfully done it by directly modifying the SDL code to do it in the ViewController, but as a user of the library API, that option isn't available to me.
I was previously thinking I could do so with a customer NSResponder, but am no longer convinced this is a valid option.
Thank you.
Creating an NSWindowController and attaching it to the existing window works.
#interface WindowController : NSWindowController <NSTouchBarDelegate>
and
- (id)init:(NSWindow *) nswindow
{
self = [super initWithWindow:nswindow];
return self;
}
- (NSTouchBar *)makeTouchBar
{
NSTouchBar *bar = [[NSTouchBar alloc] init];
bar.delegate = self;
bar.customizationIdentifier = PopoverCustomizationIdentifier;
bar.defaultItemIdentifiers = #[PopoverItemIdentifier, NSTouchBarItemIdentifierOtherItemsProxy];
bar.customizationAllowedItemIdentifiers = #[PopoverItemIdentifier];
bar.principalItemIdentifier = PopoverItemIdentifier;
return bar;
}
You can see https://developer.apple.com/library/content/samplecode/NSTouchBarCatalog/Listings/Objective_C_NSTouchBar_Catalog_TestViewControllers_PopoverViewController_m.html for a bunch more of the guts to put in these functions.

Changing UIPageViewController own PageController regarding Color of Dots

Hey I'm using a UIPageViewController to control what page I am on and for scrolling. I know it's possible to show a Page Controller along with it by simply adding the following two functions.
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
What I want to know is if it's possible to change the color of the page controller, so the dots are more visible on the background I'm using?
I know a regular page controller has the properties:
#property(nonatomic,retain) UIColor *currentPageIndicatorTintColor
#property(nonatomic,retain) UIColor *pageIndicatorTintColor
However, I can't figure out for the life of me how to access these properties or the Page Controller for that matter from UIPageViewController.
It might be helpful, if someone just said how to change the properties in general?
You can use UIAppearance to configure UIPageControl colors. This applies to UIPageControls in UIPageViewControllers too.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor whiteColor];
pageControl.currentPageIndicatorTintColor = [UIColor redColor];
}
If you would like to change the UIPageControl's colors for a specific UIPageViewController, you can use the following:
In Swift 3
let pageControl: UIPageControl = UIPageControl.appearance(whenContainedInInstancesOf: [MyPageViewController.self])
pageControl.pageIndicatorTintColor = UIColor.green
// ... any other changes to pageControl
UIPageControl conforms to UIAppearance protocol. The Apple Developper API Reference states about UIAppearance:
Use the UIAppearance protocol to get the appearance proxy for a class. You can customize the appearance of instances of a class by sending appearance modification messages to the class’s appearance proxy.
Therefore, using Swift 2.2, you may set UIPageControl's pageIndicatorTintColor and currentPageIndicatorTintColor in a subclass of UINavigationController or in your AppDelegate class (for a more global approach).
CustomNavigationController.swift:
class CustomNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
// Set pageIndicatorTintColor and currentPageIndicatorTintColor
// only for the following stack of UIViewControllers
let pageControl = UIPageControl.appearance()
pageControl.pageIndicatorTintColor = UIColor.blueColor()
pageControl.currentPageIndicatorTintColor = UIColor.greenColor()
}
}
AppDelegate.Swift:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Set pageIndicatorTintColor and currentPageIndicatorTintColor globally
let pageControl = UIPageControl.appearance()
pageControl.pageIndicatorTintColor = UIColor.blueColor()
pageControl.currentPageIndicatorTintColor = UIColor.greenColor()
return true
}
}

NSView 'window' is deprecated XCode 4

I have installed lately XCode 4+, and since on I get warning message 'window' is deprecated.
I have subclassed NSView and called it CentralView and used it to load various views dynamically. I had to subclass the NSView, because there are methods I needed to override.
In other class that controls loading central views I have created following method:
- (IBAction)showUserInfoView:(id)sender{
NSLog(#"Load new user info page");
// Try to end editing
NSWindow *w = [centralView window]; // Here I get warning 'window' is deprecated
BOOL ended = [w makeFirstResponder:w];
if (!ended) {
NSBeep();
return;
}
// Put the view in the box
NSView *v = [[viewControllers objectAtIndex:0] view];
NSArray* viewSet = [NSArray arrayWithObject: v];
[centralView setSubviews: viewSet];
}
As far as I am aware the window method in NSView is up to date. Why do I get message?
What type is centralView? What happens if you say [(NSView*)centralView window]?
It's possible that the compiler is not finding -[NSView window], but some other -window method which is deprecated. If centralView is declared as an id then the compiler doesn't know it's an NSView and has to guess.

Cocoa: Call App Delegate Method from another Class

I'm currently trying to get the path of a file from a drag and drop operation inside of a custom view, and then pass that path to my app delegate. I'm currently using the following:
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
NSPasteboard *pb = [sender draggingPasteboard];
NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject:NSFilenamesPboardType]];
NSArray *array = [[pb stringForType:type] propertyList];
//access the app delegate
NSApplication *myApplication;
myApplication = [NSApplication sharedApplication];
[myApplication uploadFiles:array];
return NO;
}
However, I keep getting a message that says that my app delegate doesn't respond to the "uploadFiles" method. It is declared inside of my app delegate. Am I accessing the NSApplication in the correct manner?
Thanks.
I believe the problem is that you're referring to the application but not its delegate. This should work:
Mac
[(YourAppDelegate *)[[NSApplication sharedApplication] delegate] uploadFiles:array]
replacing YourAppDelegate with your actual app delegate name, and being certain to #import it.