NSTableView without NSScrollView - objective-c

I'm thinking to make un-scrollable nstableview.
Is it possible to have a table view without scroll view, or maybe to extract table view from scroll view ?
thanks

I don't know if this is good practice (I'm googling about that - that's how I found your question)(Edit: why wouldn't it be?), but it is possible to get an NSTableView without the NSScrollView: drag out a 'custom view' and set it's identity to NSTableView. There you are! The only thing is you don't get any visual feedback from IB about the tableview. But you can still set outlets (the delegate, datasource etc) in IB. I am afraid you'll have to set UI options (things like 'draws background' and such) from code (at least they don't appear if you use my 'trick').
You could even do it without IB (I found this code on SO, I didn't test it):
MyDataSource *dataSource = [[MyDataSource alloc] init];
NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:#"onlyColumn"];
NSTableView *table = [[NSTableView alloc] initWithFrame: frameWhereTableViewShouldGo];
[table setDataSource:dataSource];
[table addTableColumn:column];
[theViewYouWantATableViewIn addSubview:table];

At least you can implement your NSScrollView-subclass and reimplement its scrollWheel: method.
#interface MyScrollView : NSScrollView
#property (nonatomic) BOOL scrollingEnabled;
#end
#implementation
- (void)scrollWheel:(NSEvent *)event
{
if (self.scrollingEnabled)
[super scrollWheel:event];
}
#end

Did you mean this?
self.tableView.scrollEnabled=NO;

Related

NSTextView not properly resizing with auto layout

I have a simple layout, which consists of NSView and its subview NSTextView. NSTextView is programmatically filled with some text that spawns multiple lines. I tie everything together using auto-layout (all done programmatically). However, when everything is displayed NSTextView is cut off, only one line is showing.
After searching the web, the best answer I could find was:
Using Autolayout with expanding NSTextViews
However, this only works if I manually change the text in NSTextView after everything is displayed (which is not really my use case). The views are readjusted and the whole NSTextView is displayed.
I am trying to figure out when NSViewController is done with laying out subviews so that I could call invalidateIntrinsicContentSize on the NSTextView. The equivalent of viewDidLayoutSubviews in UIViewController.
Nothing I tried worked so far. I attempted calling invalidateIntrinsicContentSize for NSTextView:
At the end of loadView
After I filled NSTextView with my text
Is there a better way to achieve this?
After further research, found the answer:
Create custom NSView subclass that contains NSTextView
In NSView subclass override layout method that calls invalidateIntrinsicContentSize
Also check out this link that explains subtleties of auto layout and intrinsic content size (among many other things):
http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html
Sample code:
#interface MyView : NSView
#property MyTextView *textView;
#end
#implementation MyView
// init & create content & set constraints
-(void) layout {
[super layout];
[self.textView invalidateIntrinsicContentSize];
}
#end
Implementation of MyTextView:
#implementation MyTextView
- (NSSize) intrinsicContentSize {
NSTextContainer* textContainer = [self textContainer];
NSLayoutManager* layoutManager = [self layoutManager];
[layoutManager ensureLayoutForTextContainer: textContainer];
return [layoutManager usedRectForTextContainer: textContainer].size;
}
- (void) didChangeText {
[super didChangeText];
[self invalidateIntrinsicContentSize];
}
#end

Xcode: Create a group of outlets

This is just a quick question, I have lots of outlets in my code that need to be hidden initially and I want to make it so that in my viewDidLoad I only have to say something along the lines of colourObjects.hidden = YES; rather than individually going through and declaring if they are hidden or not i.e. redColourObject.hidden = YES;
blueColourObjects.hidden = YES;
greenColourObjects.hidden = YES; I would find it very grateful to know if this is possible and how you do it!
Thanks for any help
Hugh
IBOutletCollection is what you need:
#property (nonatomic, strong) IBOutletCollection(UIView) NSArray *stuff;
You can drag as many outlets as you want in it and they'll be there. You can also keep the original references for other purposes. then
for (UIView *view in self.stuff) {
[view setHidden:YES];
}
Sorry but there is not a way to do that. You would have to declare that individually.
What you could do I put them all into one UIView and then hide the UIView which would hide everything in in the UIView.

TableViewController within a ViewController

I have a UIViewController (StoreViewController), and in it's .xib is a UITableView to the left, and a standard UIView to the right. I have created a UITableViewController called StoreTableController and want to somehow make it the the controller of the table view within the StoreView.xib.
Unfortunately, I need to keep the File Owner of the nib file as StoreViewController. I have a delegate within the StoreTableController which has been set as the StoreViewController (this is for calling certain methods), and within the StoreViewController I have an instance of the StoreTableController.
So far I have tried keeping an outlet of the UITableView within StoreViewController and then doing this:
[self addChildViewController:self.tableController];
[self.tableController setTableView:self.table];
[self.table setDataSource:self.tableController];
[self.table setDelegate:self.tableController];
Where self.table is the outlet, and self.tableController is the instance of the StoreTableController.
However, I do not fully understand how to use UIViewController containment, so this is obviously incorrect.
I have tried variations of this as well, but really don't know what to do.
I have avoided using a UISplitViewController here because not only is the left view larger than the right, but also there are various things I plan to do which mean this must be done in a single .xib file if possible.
Any help is very much appreciated.
First, put a regular UIView instead of a UIScrollView in your .xib. Connect it with an IBOutlet called "tableContentView".
Then, create a new instance of UITableViewController (or your custom class, derived from UITableViewController) in your code, and add its UIView to the tableContentView like so:
- (void)viewDidLoad
{
[super viewDidLoad];
// Add tableView
UITableViewController *someTableViewController = [[UITableViewController alloc] init];
someTableViewController.view.frame = self.tableContentView.bounds;
someTableViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self.tableContentView addSubview:someTableViewController.view];
}

Objective-C: Adding UIButtons programmatically from another class

I'm having trouble connecting the dots between code and .xib files.
If I want to add a series of UIButtons programmatically to my view controller, how would I go about doing this from a separate class?
For instance, if I have MainViewController.m, which is set as the root view controller in Xcode, how can I add a UIButton to that view controller from SecondViewController.m? Is this even possible?
I would essentially like to place all of my "user interface" code in a separate class.
Thanks
To do this, create a UIButton *myButton programmatically and then call [mainViewController addSubview:myButton];. This may mean you need to store a MainViewController * property in your SecondViewController class.
Important methods and properties for a UIButton instance (essentially, just take a look at the documentation, but here's a minimal set of stuff to get you started):
+[UIButton buttonWithType:buttonType] - Make sure if you're doing anything remotely custom to use UIButtonTypeCustom here (it doesn't give you any default background images or otherwise to have to nil out)
setFrame: - Position the button relative to its container and set the size, for usability reasons the width and height should be at least 44 pixels (as mentioned here).
setTitle:forState: - UIControlStateNormal will act as the default properties for other states too, so you may only need to set the text here
setBackgroundImage:forState: - use UIControlStateNormal and UIControlStateHighlighted/UIControlStateSelected primarily, UIControlStateDisabled if you wish to show it grayed out or inaccessible at any point.
setImage:forState: - Use for an icon next to the button text (like an arrow pointing down for Save or up for Load, etc)
setEnabled:, setHidden:, setSelected: - Transition between different button states. setHighlighted: happens automatically when you tap the button.
addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside - TouchUpInside is almost always what you want for a simple button press, I'm using a method named buttonClicked: here to handle my button press.
Oh, and if you use [[UIButton alloc] initWith...] don't forget to [myButton release] once it's added to the mainViewController :)
use this
#import "MainViewController.h"
#interface SecondViewController
{
MainViewController *mainView;
}
#property(nonatomic, retain) MainViewController *mainView;
-(void)addButtons;
In your implementation
#synthesize mainView;
-(void)addButtons
{
UIButton *add = [UIButton alloc] init];
//do necessary stuff on button here
[self.mainView addSubview:add];
[add release];
}
In your MainViewcontroller.m
#import "SecondViewController.h"
-(void)viewDidLoad
{
[self superViewDidLoad];
SecondViewController *second = [SecondViewController alloc] init];
second.mainView = self;
[second addButton];
[second release];
}

how to use UITableViewStyleGrouped at the initialization?

i found this link : initialize UITableViewController with [super initWithStyle:UITableViewStyleGrouped]
but i don't understand the way to initialize the tableView as "grouped" inside the controller class?
self = [super initWithStyle:UITableViewStyleGrouped];
Could you help me?
Thanks a lot
Paul
[self.tableView initWithFrame:self.view.frame style:UITableViewStyleGrouped];
The easiest way is to change the TableView in Interface Builder to Grouped style in the Attribute Inspector. To do this in code you would need to change the way the UITableViewControler is created. You would not do it through the xib, but in code in the AppDelegate. You could also change the code to a UIViewController and implement the table view delegates and change things yourself.
Not sure if this is what you are looking for, but assuming you have a UITableViewController called myTableVC that is created via code (with no xib) and you want the table to display with a grouped style, you could do so by calling the view controller as follows:
MyTableViewController *myTableVC= [[MyTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
[self presentModalViewController:myTableVC animated:YES];
[myTableVC release];
Similarly, if you wanted a plain tableviewcontroller style, you could do so by:
MyTableViewController *myTableVC= [[MyTableViewController alloc] initWithStyle:UITableViewStylePlain];