Window Sizing issue - resize

I am creating a minimal WebKit browser for a Mac OS App using the following Swift code to load the new WKWebView into an Custom View Object.
The following line of code creates the web view to fill the size of the customView window:
var theWebView:WKWebView = WKWebView(frame:self.customView.frame)
When you run the App the web page loads correctly to fill the window, however if the window is resized the web page does not resize with the window.
I have added constraints to the Custom View object in interface builder and believe that this object is resizing correctly however it seems that the WKWebView is not adjusting to fill the Custom View?
See attached screen shots below.
Any ideas welcome.
import Cocoa import WebKit
#NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate
{
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var customView: NSView!
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
//create a URL for the path
var url = NSURL(string:"http://www.google.com/")
//create a request for the URL
var request = NSURLRequest(URL:url!)
//create the WKWebView and set the size to match
//the window's full view
var theWebView:WKWebView = WKWebView(frame:self.customView.frame)
//have the web view load the page
theWebView.loadRequest(request)
//add the web view to the main window
self.customView.addSubview(theWebView)
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
} }

I had this same issue (in Objective-C) and solved it by putting this one line of code in right after I added webView as a subview.
webView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;

Related

Change navigation root view programmatically objective c

I want to change the navigation's root view controller programmatically using objective c. I am using a storyboard. I tried to change it in-app delegate but didn't work, there's something new introduced called scene delegate where I believe I can change the root from there, but I found no resources for that matter. Can anyone help?
Use below code:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = MyRootViewController()
self.window = window
window.makeKeyAndVisible()
}
}
Reference: https://www.andrewcbancroft.com/blog/ios-development/ui-work/accessing-root-view-controller-ios13-scenedelegate/
And: How set rootViewController in Scene Delegate iOS 13

Autolayout is not working with NSSplitView and NSPageController with Storyboard. Is this Apple Bug?

I just created a empty project on github --> here <-- to demonstrate the problem (Done in objective-c)
The project is a simple storyboard project. An NSWindowController loads an NSPageController which loads a NSSplitView containing 3 panes. There is no code in the sample project, except the code to load the screens. When the project runs, it looks like this .
How do I get the constraints to make the splitView stretch all the way to the ends when the window is resized? The weird thing is, if you Switch the NSWindowController's contentController from the NSPageController to the NSSplitViewController, then every thing works as expected. Is this Apple Bug? I would appreciate any answer swift/objectivec please. I've tried but nothing works.
[EDIT] - Based on the answer below and further researching (contacted Apple), it appears that NSPageViewController does not use autolayout constraints but relies on autoresizing mask and frame setting on its children views.
So when the page controller creates its view controllers, we should set this:
-(NSViewController *)pageController:(NSPageController *)pageController viewControllerForIdentifier:(NSString *)identifier {
NSViewController *viewController = [self.storyboard instantiateControllerWithIdentifier:identifier];
[viewController.view setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)];
return viewController;
}
With this, the problem is fixed. I wish as an update in future, this control works with Autolayout constraints as it seems more natural.
I had many problems with NSPageController. I found that the solution is to not use auto layout with it.
Try to use the NSAutoresizingMaskOptions on your NSSplitView.
First, remove all constraints inside the NSPageController.
Then:
splitView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
splitView.frame = pageController.view.bounds;
or
splitView.autoresizingMask = [.ViewWidthSizable, .ViewHeightSizable]
splitView.frame = pageController.view.bounds
EDIT
Made a project based on yours here
I also got same issue in Pagecontroller:
And solved it by using the given code:
func pageController(_ pageController: NSPageController, viewControllerForIdentifier identifier: String) -> NSViewController {
switch identifier {
case "formController":
let controller = NSStoryboard(name: "Main", bundle:nil).instantiateController(withIdentifier: "formController") as! FormController
controller.view.autoresizingMask = [.height , .width]
return controller
default:
return self.storyboard?.instantiateController(withIdentifier: identifier) as! NSViewController
}
}
func pageController(_ pageController: NSPageController, identifierFor object: Any) -> String {
return String(describing: object)
}
func pageControllerDidEndLiveTransition(_ pageController: NSPageController) {
print(pageController.selectedIndex)
pageController.completeTransition()
pageController.selectedViewController!.view.autoresizingMask = [.height , .width]
}

NSBox is not showing methods to add content in it (Swift)

I would need to add some contents inside a NSBox, an Image and some text.
To do that I use the methods of NSBox class and call them on the object.
I created an IBOutlet:
#IBOutlet weak var theBox: NSBox!
and I also have a button, once I click it, the box will be filled with text (NSTextField):
#IBAction func filler(sender: AnyObject)
{
var label: NSTextField! = NSTextField() //Initialized a label to put it in the box
label.stringValue = "My text hey hey hey!"
theBox.setContentView(label) //I GET AN ERROR MESSAGE HERE
}
to add the content I used .setContentViewbut this method is not callable on the object theBoxand I don't know why I am wrong. Look at the documentation. The method exists and it is callable on the NSBox objects.
I'm new with swift and OSX development. Any Idea?
In Swift, you don't call the set methods for properties, you just assign to them directly:
theBox.contentView = label

XCode doesn't load a custom view

I have created a custom view for an error message.
I created an ErrorView.swift sub classing UIView and I created also an ErrorView.xib to use in Interface Builder.
In the identity inspector I set the custom class of the xib as ErrorView.swift but
when I try to load this specific view it doesn't work.
Why? Can you help me?
This is the code:
My personalized class named ErrorView
Class ErrorView: UIView {
class func errorInView(view:UIView, animted:Bool) -> ErrorView {
println("ERROR VIEW LOADED")
let errorView = ErrorView(frame: view.bounds)
errorView.opaque = false
view.addSubview(errorView)
return errorView
}
}
my xib:
http://i59.tinypic.com/23tnlev.png
This is the code I use in my ViewController to call the view.
let errorView = ErrorView.errorInView(self.view, animted: true)
The problem here is that you are not loading your xib, instead you are creating a new Error View in code.
If you add errorView.backgroundColor = UIColor.greenColor() after errorView is created, but before you add it as a subview you will see the screen turn green. I have posted this example as a gist.
If you want to create your view from the xib you will have to load the xib using the normal NSBundle.mainBundle() call.
let errorView = NSBundle.mainBundle().loadNibNamed("ErrorView", owner: self, options: nil)[0] as ErrorView
instead of creating the view with the ErrorView(frame:)
This example is also a gist.

How do I modify the automatically generated About window in my Cocoa app?

A menu item for "About MyApp" was automatically created for me and it displays an about window. How do I edit this window? I'd like to add some extra stuff there but I can't find the xib anywhere.
Thanks!
Modify the contents of Credits.rtf file located inside the 'supporting files' group of your project.
A menu item for "About MyApp" was automatically created for me and it
displays an about window.
This is standard with Xcode templates for Cocoa apps. Keep reading to see how it is wired.
How do I edit this window? I'd like to add some extra stuff there but
I can't find the xib anywhere.
There is no xib: This window is created at runtime by the application object ([NSApplication sharedApplication]), when it receives the message orderFrontStandardAboutPanelWithOptions:, which that menu item sends when selected (as you an verify in the Connections Inspector in Interface Builder).
By default (as others have mentioned), it loads the contents to display from a file named "Credits.rtf" if such file exists within your app bundle's resources; otherwise it grabs basic info from your app's Info.plist entries:
App name
Bundle version
Copyright notice
What you can do is override this behaviour as follows:
Create a custom "About" window in Interface builder, with all the subviews and labels you want. Name the file "AboutWindow.xib".
Create a custom NSWindowController subclass, initialized with your custom window's nib name and set as the nib's owner:
- (instancetype) init {
if(self = [super initWithWindowNibName:#"AboutWindow" owner:self]){
// (other initialization...)
}
return self;
}
Connect your About window's subviews to outlets in the window controller class.
Also, specify the class for File Owner as your custom NSWindowController subclass and connect the window's "New Referencing Outlet" to File Owner's window property.
Go to MainMenu.xib in Interface Builder. Remove the action that is wired to the menu item "About ...", and re-wire a new one to the about: method of the placeholder object "First Responder".
In your app delegate, add an instance variable to hold your window controller so it does not get deallocated right away (alternatively, make your window controller class a singleton and use the shared instance):
#implementation AppDelegate {
AboutWindowController *_aboutwindowController;
}
Still in AppDelegate, implement the method about: that you wired in step 3, like this:
- (IBAction)about:(id)sender {
if (_aboutwindowController == nil) {
_aboutwindowController = [AboutWindowController new];
}
[_aboutwindowController.window orderFront:self];
}
...or, if your view controller is implemented as a singleton, like this:
- (IBAction)about:(id)sender {
[[AboutWindowController defaultController].window orderFront:self];
}
Finally, in order for your window controller to correctly display your app's information, read the relevant keys from the Info.plist file, like this (actual outlet ivars will be different in you case):
- (void)windowDidLoad {
[super windowDidLoad];
// Implement this method to handle any initialization after your window
// controller's window has been loaded from its nib file.
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
self.appNameLabel.stringValue = [infoDictionary objectForKey:#"CFBundleName"];
self.appVersionLabel.stringValue = [infoDictionary objectForKey:#"CFBundleShortVersionString"];
self.appCopyrightLabel.stringValue = [infoDictionary objectForKey:#"NSHumanReadableCopyright"];
}
You might be tempted to read the app icon from the bundled resources too, but there's a more elegant way that works even if you didn't specify an icon and are stuck with the default "Ruler + Pencil + Brush over a Sheet" app icon: Grab the runtime icon image using the following code:
self.appIconImageView.image = [NSApp applicationIconImage];
I have put together a demo project on Github that shows this and further customizations of the About window.
UPDATE: I have added a Swift version of the demo project to the Github repository.
It features:
Swift 4 (now that Xcode 9 is official)
Storyboards instead of xibs
Moved all the outlets to the new view controller, kept window appearance code in the window controller.