Subclass UISplitViewController and set custom width - objective-c

I'm trying to subclass UISplitViewController to decrease the width of the master. I've looked at Matt Gemmell's MGSplitViewController - see Change the width of Master in UISplitViewController - but it looks like way more than I need. I just want to decrease the size of the master from 320 to 260 in a way that Apple will accept in the app store.
I'm new to subclassing anything other than a button, but this is what I'm trying so far, although it currently doesn't do anything. Either I'm way off the mark or I'm missing something simple. How can this be done?
Header file:
#import <UIKit/UIKit.h>
#interface MYSplitViewController : UISplitViewController
+ (CGFloat)masterColumnWidth;
#end
Implementation file:
#import "SRSplitViewController.h"
#interface SRSplitViewController ()
#end
#implementation SRSplitViewController
+ (CGFloat)masterColumnWidth {
return 260;
}
#end

I ended up not going this route, and would recommend against trying to subclass UISplitViewController for others. It's not a flexible layout so unless you want exactly what it provides out of the box, you are going to run into time-consuming problems.
If you want a side navigation bar similar to the Facebook app, I'd recommend using JASidePanels and placing whatever size and style view controller you want in the left panel.

Related

Core Plot: Cursor does not adjust over CPTGraphHostingView

I use Core Plot in two macOS apps (first one is old, second one is new). Each of them has a CPTGraphHostingView where some plots are displayed. I can click, hold and drag to change the visible area.
In the first app, when I hoover over the plot, the cursor changes to an open hand. It also changes to a closed hand when I drag. This is what I want, and this is the behaviour in all the sample apps of Core Plot.
In the second app, the cursor always stays the same (arrow).
Edit: Here is a screenshot of the view hierarchy in Xcode (views behind the plot view are hidden). There is no view in front of the CPTGraphHostingView, just a few controls are higher in the view hierarchy, but they are positioned around the plot.
I was not able to find any difference between my two apps (or the second app and the example apps) that could cause this. Both apps compile with Xcode 10.1 and Core Plot release-2.3 branch.
What should I look for?
Check that there aren't any other invisible views obscuring the Core Plot hosting view. Does everything else in the second app (layout, appearance, etc.) work the way you expect?
Since initWithFrame of CPTGraphHostingView does not get called in my second app, the hand cursers are always nil and cannot be adjusted. This is from Apple's docs for "Creating a Custom View":
View instances that are created in Interface Builder don't call
initWithFrame: when their nib files are loaded, which often causes
confusion. Remember that Interface Builder archives an object when it
saves a nib file, so the view instance will already have been created
and initWithFrame: will already have been called.
The awakeFromNib method provides an opportunity to provide
initialization of a view when it is created as a result of a nib file
being loaded. When a nib file that contains a view object is loaded,
each view instance receives an awakeFromNib message when all the
objects have been unarchived. This provides the object an opportunity
to initialize any attributes that are not archived with the object in
Interface Builder.
So I subclassed CPTGraphHostingView and loaded the cursors from NSCursor in awakeFromNib, using the advice from Eric Skroch:
MyGraphHostingView.h:
#import <CorePlot/CorePlot.h>
NS_ASSUME_NONNULL_BEGIN
#interface MyGraphHostingView : CPTGraphHostingView
#end
NS_ASSUME_NONNULL_END
MyGraphHostingView.m:
#import "MyGraphHostingView.h"
#implementation MyGraphHostingView
-(void)awakeFromNib
{
[super awakeFromNib];
if (!self.closedHandCursor) {
self.closedHandCursor = [NSCursor closedHandCursor];
}
if (!self.openHandCursor) {
self.openHandCursor = [NSCursor openHandCursor];
}
self.allowPinchScaling = YES;
}
#end

What's the difference between UIViewController and ViewController?

I just noticed after adding a new ViewController that it isn't a UIViewController like the one created by Xcode. I didn't find an answer on google so I hope one of you could explain the difference between these two to me.
Edit
To clarify my question:
This is the declaration of my UIViewController:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
And this is the declaration of my ViewController:
#import "ViewController.h"
#interface GameViewController : ViewController
What is the difference between these two ViewControllers?
What is the difference between these two ViewControllers?
Not a great deal, but it depends on the functionality defined in ViewController. It's fairly common to create a base class that contains common functionality you want in all derived classes, and view controller classes are no exception here.
However if ViewController contains no real functionality, then you can simply remove it and derive GameViewController directly from UIViewController:
#import <UIKit/UIKit.h>
#interface GameViewController : UIViewController
I would be very surprised if Xcode generated both ViewController and GameViewController in one operation, as you imply in your question, however. If it did, then that's new to me and I cannot see why it did it.
UIViewController provides infrastructure of the view, and when you make your own ViewController it is inherited from UIViewController. Just to be clear: you do not modify UIViewController, you subclass it, and then modify by your own.
UIViewController is a class provided by Apple. In order to perform UI customization for your app, you usually create subclasses of UIViewController.
ViewController is an example subclass of UIViewController.
A View Controller is a concept, is what manages a part of your user interface and interaction.
Based on the documentation:
View controllers are the foundation of your app’s internal structure. Every app has at least one view controller, and most apps have several. Each view controller manages a portion of your app’s user interface as well as the interactions between that interface and the underlying data. View controllers also facilitate transitions between different parts of your user interface.
An UIViewController is just the base class of this already defined "View Controller", you add a viewController as you said, but a viewController has a class associated to it, that can be a UIViewController, UITableViewController, or variations/subclasses.

Is it possible for Multiple UIViewControllers to Share the same code?

I'm making a app with mutiple view controllers, one moves on to the next and once the user moves on to the next view there is no need to go back.
I have created the .m .h files for the view controllers that I need to play sounds on.
What I would like help with is disabling copy/paste/define in UITextview which I know how to do (and works fine) using
#interface MyUITextView : UITextView {
}
#end
#implementation MyUITextView
- (BOOL)canBecomeFirstResponder
{
return NO;
}
Is there a way of using this code once with out creating .m .h files for each and every uiveiwcontroller?
Or will Xcode allow me to assign the same name to more than one uiveiwcontroller and use the same piece of code?
Is it possible to write it into the AppDelegate for every UITextview on different controllers?
Thanks for any help in advance :)
You don't have to duplicate any code. If you're making your UI using xib files or a storyboard, just set the class name of any text views that you want to have behave this way to MyUITextView in Xcode's Identity inspector.

NSStatusItem with NSPopover and NSTextField

I have a NSStatusItem that displays a NSPopover which contains a NSTextField but the text field isn't editable although it has been so be so in Xcode. Now this is a known bug and there is apparently a solution someone posted here. I really need to work around this bug.
I'll just quote the answer here for convenience:
The main problem is the way keyboard events works. Although the NSTextField (and all his superviews) receives keyboard events, he doesn't make any action. That happens because the view where the popover is atached, is in a window which can't become a key window. You can't access that window in no way, at least I couldn't. So the solution is override the method canBecomeKeyWindow for every NSWindow in our application using a category.
NSWindow+canBecomeKeyWindow.h
#interface NSWindow (canBecomeKeyWindow)
#end
NSWindow+canBecomeKeyWindow.m
#implementation NSWindow (canBecomeKeyWindow)
//This is to fix a bug with 10.7 where an NSPopover with a text field cannot be edited if its parent window won't become key
//The pragma statements disable the corresponding warning for overriding an already-implemented method
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (BOOL)canBecomeKeyWindow
{
return YES;
}
#pragma clang diagnostic pop
#end
That makes the popover fully resposive. If you need another window which must respond NO to canBecomeKeyWindow, you can always make a subclass.
I don't really understand what I am supposed to do. Do I just create these two files NSWindow+canBecomeKeyWindow (.h and .m) and that will do it? Because it doesn't work for me.
I am not sure about this but does this only work if I am actually using an NSWindow that displays the NSPopover? I am not using a NSWindow, how can I get the NSTextField to be editable?
Thanks.
Yes, just add the NSWindow+canBecomeKeyWindow (.h and .m) files to your project, and it should work. I'm using this technique in an app I'm currently developing, and it works fine. Make sure NSWindow+canBecomeKeyWindow.m is listed under "Compile Sources" in your project's Build Phases.
As an aside, I'm having other issues using NSPopover to show a window from an NSStatusItem. I haven't actually tried using it in my project, but this looks promising as an alternative.

Associating a UITableView with a TableViewController

Can anyone describe how it is possible to have a TableViewController with its xib file having a at its root and the uitableview as a subview?
I believe the TVController somehow assumes that UITableView will fill the entire area.
Why is that?
I have a really specific need to build a kind of side and bottom tabbed interface with a UITableView as its main area. Pressing tabs changes the predicate for the fetchedresultscontroller etc etc.
The reason I want this is because of the breadth and depth of the data categories in the data model. I rally need to flatten the menu structure a lot...other wise with a table and navbar controller structure, user experience will be akin to sinking to ever deeper depths of a cavern!
My idea is tried and true in other paradigms...in iOS it almost looks like it's Apple's way or the highway. I am OK with APPLE of course no gripe.
But I really would like to create this.
I tried adding a new tableviewcontroller complete with xib and then removing the UITableView in IB and replacing with a UIView and a UITableView as a subview, hooking up (I believe) the delegate to the file's owner.
I created an IV tableView for when I want to reference it and again used IB to hook it up in IB
Try to run it and it whines that...
[UITableViewController loadView] loaded the "TabbedTableController" nib but didn't get a UITableView.'
Really can't seem to get my head around what the issue is here.
There doesn't appear to be anymore I can do to hook the UITableView up!
Any help would be terrific. I'll send you a Christmas card in desperation :^)
Also...why should it be so and how strict is this UITableView fullscreen thing?
Enlighten me if you can. The docs I have read don't want to.
Regards
Keith
A UITableViewController does assume that the root view (i.e. the controller's view property) will be a UITableView, thus the table view fills the screen. When you need a view that combines UITableView with other top level views, you will need to do a little more work but it's not hard:
Your view controller will not subclass UITableView. Instead, do this:
#interface MyViewController : UIViewController
<UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, weak) IBOutlet UITableView* tableView;
In Interface Builder, drop in a UITableView and whatever other controls you need. The table view can be any size and in any location in the view hierarchy. Also in Interface Builder, ctrl-drag from the table view to your VC and set the delegate and dataSource outlets, and ctrl-drag from your VC to the table view to set the tableView outlet.
Your view controller implementation should be the typical table view controller implementation: cellForRowAtIndexPath, etc.
A UITableViewController is more or less just all of the above work packaged up into a single unit for you.