Resizing tableview height programmatically - xcode

I am using storyboard in xcode 4.5.
In my application there is 2 views, view1 and view2.
Each view has a tableview.
A navigation controller is connected to the views.
I am trying to change the height of the tableview depending on the size of the Iphone display.
I am using the following code:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Verify if the screen is iphone 5
if ([[UIScreen mainScreen] bounds].size.height == 568){
// Resize table hight
CGRect tvframe = [_myTableView frame];
[_myTableView setFrame:CGRectMake(tvframe.origin.x,
tvframe.origin.y,
tvframe.size.width,
tvframe.size.height + 64)];
}
The problem is that the code has no effect when the application starts and view1 appears.
But when I move to view2 and then back to view1 the resizing takes effect.
I don't understand why the reszing doesn't take effect when the application starts.

Have you tried moving the code to ViewWillAppear? That should fix the problem.

Related

NSTextField Drawing on Top of Sub View

I have created a secondary NSViewController to create a progress indicator "popup". The reason for this is that the software has to interact with some hardware and some of the functions take the device a few seconds to respond. So being thoughtful of the end user I have a NSViewController that has a NSView (that is black and semi-transparent) and then a message/progress bar on top. This is added to the window using addSubView.
Everything works great except when the screen has a NSTextField in it. The popup shows but the NSTextField is drawn on top. What is this?
The view code I used for drawing semi-transparent:
#implementation ConnectingView
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
// Drawing code here.
CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
CGContextSetRGBFillColor(context, 0.227,0.251,0.337,0.8);
CGContextFillRect(context, NSRectToCGRect(dirtyRect));
}
#end
The code I use to show the progress view
-(void) showProgressWithMessage:(NSString *) message andIsIndet:(BOOL) indet
{
connectingView = [[ConnectingViewController alloc] init];
[self.view.window.contentView addSubview:connectingView.view];
connectingView.view.frame = ((NSView*)self.view.window.contentView).bounds;
[connectingView changeProgressLabel:message];
if (indet)
[connectingView makeProgressBar:NO];
}
Is there a better way to add the subview or to tell the NSTextFields I don't want them to be drawn on top?
Thanks!
So Setting [self setWantsLayer] to my custom NSViews sort of worked however there are a lot of redraw issues (white borders, and backgrounds). A NSPopover may be better in some instances however I was going for "locked down" approach where the interface is unreachable until it finishes (or times out).
What worked for me was to go to the instance of my NSView, select the window in Interface Builder, then go to layers (far right on properties view) and select my view under "Core Animation Layer".

UIScrollView not scrolling horizontally despite setting contentSize

I have a simple app with multiple UITableViews, all of whom redirect to a single ViewController, with 2 items: a Label, and an ImageView embedded into a scrollview.
The problem is, the image, even though resized to exceed the screen size, does not scroll horizontally. It only scrolls vertically.
GammaViewController.h :
IBOutlet UIScrollView *testScroll;
GammaViewController.m :
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.title = #"Gamma View";
finalLabel.text= _selectedData;
[testScroll setScrollEnabled:YES];
[testScroll setContentSize:CGSizeMake(600,800)];
}
The ImageView has been assigned an image from the Attributes inspector, and has been resized to the scrollview contentSize i.e. (600,800).
May be a silly mistake that content size and frame may be same.
Try this
[testScroll setFrame:CGRectMake(0,0,320,400)];
[testScroll setContentSize:CGSizeMake(600,800)];
May this code help you.

How to develop for multiple iOS devices, i.e. multiple storyboards?

I am currently developing an app for the iPhone 3GS. The deployment target is set to 5.1 and I have created a rich storyboard with lots of segues and scenes. Last night I had the idea that I wanted to make the app available for the iPad, iPhone 4, and iPhone 5. I decided to create a separate storyboard for the different screen sizes / resolutions. Now I am not sure if this is the best practice, as I have just recently started reading about springs and struts on SO, so I don't know much information about it, but for my sake, I just wanted to launch a different storyboard when the application finished launching. However this desired effect is not happening.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// ViewControllerWelcome *viewControllerWelcome = (ViewControllerWelcome *)[[ViewControllerWelcome alloc]init];
// NSManagedObjectContext *context = (NSManagedObjectContext *) [self managedObjectContext];
// if (!context) {
// NSLog(#"\nCould not create *context for self");
// }
//[viewControllerWelcome setManagedObjectContext:context];
// Do I need to declare my view controllers here?
// Pass the managed object context to the view controller.
CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;
if (iOSDeviceScreenSize.height == 480)
{
// Instantiate a new storyboard object using the storyboard file named iPhoneLegacy
UIStoryboard *iPhoneLegacy = [UIStoryboard storyboardWithName:#"iPhoneLegacy" bundle:nil];
// Instantiate the initial view controller object from the storyboard
UIViewController *ViewControllerWelcome = [iPhoneLegacy instantiateInitialViewController];
// Instantiate a UIWindow object and initialize it with the screen size of the iOS device
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Set the initial view controller to be the root view controller of the window object
self.window.rootViewController = ViewControllerWelcome;
// set the window object to be the key window and show it
[self.window makeKeyAndVisible];
}
if (iOSDeviceScreenSize.height == 968)
{
// Instantiate a new storyboard object using the storyboard file named iPhone4
UIStoryboard *iPhone4 = [UIStoryboard storyboardWithName:#"iPhone4" bundle:nil];
UIViewController *ViewControllerWelcome = [iPhone4 instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = ViewControllerWelcome;
[self.window makeKeyAndVisible];
}
// iPhone 5 1136 x 640
// iPad Legacy 1024 x 768
return YES;
}
When I try testing to see if the different storyboard file are loading in the Simulator, Simulator just loads the iPhoneLegacy storyboard.
Does this code only work for the physical devices, and do I need separate code for the Simulator?
Fist of all, DELETE YOUR EXTRA STORYBOARDS! You only need one for the iPhone and one for the iPad.
There is a simple way to make a single storyboard for all iPhone/iPod Touch sizes.
Keep only ONE storyboard for the iPhone screen size (including iPhone 5).
Make a #2x file for all of your images.
To switch between 3.5 and 4 inch size, Apple provides a button in the bottom right that looks like a rectangle with arrows pointing in or out - that button will switch between the 3.5 and 4 inch screen sizes.
That's it! No code is actually needed to make a single storyboard for each iPhone/iPod Touch.
For the iPad, you are going to need to create a new storyboard that is made for the iPad and you are going to need to update your UI code to make sure it's compatible with both iPhone and iPad screen sizes. Again, make sure to make #2x image sizes for the iPad as well.

Two Finger Drag with IKImageView and NSScrollView in Mountain Lion

I have a Mac App that's been in the app store for a year or so now. It was first published with target SDK 10.7, Lion. Upon the update to Mountain Lion it no longer works.
The application displays large images in an IKImageView which is embedded in an NSScrollView. The purpose of putting it into a scrollview was to get two finger dragging working, rather than the user having to click to drag. Using ScrollViewWorkaround by Nicholas Riley, I was able to use two finger scrolling to show the clipped content after the user had zoomed in. Just like you see in the Preview app.
Nicholas Riley's Solution:
IKImageView and scroll bars
Now in Mountain Lion this doesn't work. After zooming in, pinch or zoom button, the image is locked in the lower left portion of the image. It won't scroll.
So the question is, what's the appropriate way to display a large image in IKImageView and have two finger dragging of the zoomed image?
Thank you,
Stateful
Well, Nicholas Riley's Solution is an ugly hack in that it addresses the wrong class; the issue isn't with NSClipView (which he subclassed, but which works just fine as is), but with IKImageView.
The issue with IKImageView is actually quite simple (God knows why Apple hasn't fixed this in what? … 7 years ...): Its size does not adjust to the size of the image it displays. Now, when you embed an IKImageView in an NSScrollView, the scroll view obviously can only adjust its scroll bars relative to the size of the embedded IKImageView, not to the image it contains. And since the size of the IKImageView always stays the same, the scroll bars won't work as expected.
The following code subclasses IKImageView and fixes this behavior. Alas, it won't fix the fact that IKImageView is crash-prone in Mountain Lion as soon as you zoom …
///////////////////// HEADER FILE - FixedIKImageView.h
#import <Quartz/Quartz.h>
#interface FixedIKImageView : IKImageView
#end
///////////////////// IMPLEMENTATION FILE - FixedIKImageView.m
#import "FixedIKImageView.h"
#implementation FixedIKImageView
- (void)awakeFromNib
{
[self setTranslatesAutoresizingMaskIntoConstraints:NO]; // compatibility with Auto Layout; without this, there could be Auto Layout error messages when we are resized (delete this line if your app does not use Auto Layout)
}
// FixedIKImageView must *only* be used embedded within an NSScrollView. This means that setFrame: should never be called explicitly from outside the scroll view. Instead, this method is overwritten here to provide the correct behavior within a scroll view. The new implementation ignores the frameRect parameter.
- (void)setFrame:(NSRect)frameRect
{
NSSize imageSize = [self imageSize];
CGFloat zoomFactor = [self zoomFactor];
NSSize clipViewSize = [[self superview] frame].size;
// The content of our scroll view (which is ourselves) should stay at least as large as the scroll clip view, so we make ourselves as large as the clip view in case our (zoomed) image is smaller. However, if our image is larger than the clip view, we make ourselves as large as the image, to make the scrollbars appear and scale appropriately.
CGFloat newWidth = (imageSize.width * zoomFactor < clipViewSize.width)? clipViewSize.width : imageSize.width * zoomFactor;
CGFloat newHeight = (imageSize.height * zoomFactor < clipViewSize.height)? clipViewSize.height : imageSize.height * zoomFactor;
[super setFrame:NSMakeRect(0, 0, newWidth - 2, newHeight - 2)]; // actually, the clip view is 1 pixel larger than the content view on each side, so we must take that into account
}
//// We forward size affecting messages to our superclass, but add [self setFrame:NSZeroRect] to update the scroll bars. We also add [self setAutoresizes:NO]. Since IKImageView, instead of using [self setAutoresizes:NO], seems to set the autoresizes instance variable to NO directly, the scrollers would not be activated again without invoking [self setAutoresizes:NO] ourselves when these methods are invoked.
- (void)setZoomFactor:(CGFloat)zoomFactor
{
[super setZoomFactor:zoomFactor];
[self setFrame:NSZeroRect];
[self setAutoresizes:NO];
}
- (void)zoomImageToRect:(NSRect)rect
{
[super zoomImageToRect:rect];
[self setFrame:NSZeroRect];
[self setAutoresizes:NO];
}
- (void)zoomIn:(id)sender
{
[super zoomIn:self];
[self setFrame:NSZeroRect];
[self setAutoresizes:NO];
}
- (void)zoomOut:(id)sender
{
[super zoomOut:self];
[self setFrame:NSZeroRect];
[self setAutoresizes:NO];
}
- (void)zoomImageToActualSize:(id)sender
{
[super zoomImageToActualSize:sender];
[self setFrame:NSZeroRect];
[self setAutoresizes:NO];
}
- (void)zoomImageToFit:(id)sender
{
[self setAutoresizes:YES]; // instead of invoking super's zoomImageToFit: method, which has problems of its own, we invoke setAutoresizes:YES, which does the same thing, but also makes sure the image stays zoomed to fit even if the scroll view is resized, which is the most intuitive behavior, anyway. Since there are no scroll bars in autoresize mode, we need not add [self setFrame:NSZeroRect].
}
- (void)setAutoresizes:(BOOL)autoresizes // As long as we autoresize, make sure that no scrollers flicker up occasionally during live update.
{
[self setHasHorizontalScroller:!autoresizes];
[self setHasVerticalScroller:!autoresizes];
[super setAutoresizes:autoresizes];
}
#end

Use NSScrollView together with Cocos2d-mac (NSOpenGLView)

Has anybody used a NSScrollView to control scrolling using the cocos2d-mac framework?
After much struggling I managed to make UIScrollView work with cocos2d-ios. Any pointers to using NSScrollView together with a NSOpenGLView would be appreciated.
I finally managed to get a NSScrollView working within my cocos2d-mac Xib.
The trick is that you have to programmatically overlay the OpenGLView over the NSScrollView main view (leaving room for the scroll bars) by first setting up a fake view as the scrollView's documentView, and then removing the openGLView from its parent view and adding it again (so the OpenGLView is drawn over the ScrollView). You can do it as follows:
appDelegate = [[NSApplication sharedApplication] delegate];
// Set up NSScrollView with dummy empty view as big as the layer
NSRect rect = NSMakeRect(0, 0, myLayer.width, myLayer.height);
NSView *view = [[NSView alloc] initWithFrame:rect];
appDelegate.scrollView.documentView = view;
[view release];
// Push OpenGLView back to front
[appDelegate.glView removeFromSuperview];
[appDelegate.splitLeftView addSubview:appDelegate.glView];
And then, you should use the scroll bars events to update the myLayer position accordingly.

Resources