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.
Related
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.
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
I have a scrollview which has to display a view larger than the available display area.
I want to easily design the user interface without moving the embedded view up and down every time I have to do some changes.
The problem is everything outside the visible area is invisible in IB.
Is there any switch or trick to make everything visible in IB?
UPDATE
I have posted another solution here which I think is simpler and better, and works in storyboards.
ORIGINAL
Create your scroll view in the nib with the appropriate superview, position, and size.
Next, create a completely separate, top-level UIView instance by dragging a UIView out of the palette and dropping it into the work area outside of any existing views. In the Attributes inspector, set the Size popup to “None” and make sure the Status Bar, Top Bar, and Bottom Bar are all set to None. Here's an example:
This new top-level view will be your content view. Give your view controller two outlets: scrollView and contentView:
#interface MyViewController
#property (nonatomic, weak) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) IBOutlet UIView *contentView;
#end
In the nib, wire up the scrollView outlet to the scroll view and wire up the contentView outlet to the content view.
Build your content view hierarchy inside the content view. Set its size as large as you need - it can be larger than 320x480 (as long as you have set all of its bars to None).
In your view controller's viewDidLoad, add contentView as a subview of scrollView and set scrollView.contentSize to the size of contentView:
#implementation MyViewController
#synthesize scrollView = _scrollView;
#synthesize contentView = _contentView;
- (void)viewDidLoad {
[super viewDidLoad];
[self configureScrollView];
}
- (void)configureScrollView {
CGSize size = self.contentView.bounds.size;
self.contentView.frame = CGRectMake(0, 0, size.width, size.height);
[self.scrollView addSubview:self.contentView];
self.scrollView.contentSize = size;
// If you don't use self.contentView anywhere else, clear it here.
self.contentView = nil;
// If you use it elsewhere, clear it in `dealloc` and `viewDidUnload`.
}
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.
My NSWindow's contentView is an NSView subclass. It has some other NSView subclasses as subviews. The subviews are layer-based, and those layers in turn contain sublayers. Some of the sublayers have further sub-sublayers.
I want the whole thing to resize proportionally when the window is resized. What is the right way to set it up so that will happen?
Thanks
EDIT: I am not using Interface Builder at all.
Here's what I've done to get the contents of an NSView to scale proportionally as I resize the parent window. First, in interface builder, I added my NSView to the window, then added a reference to it in my AppDelegate. Mine happens to be called scrollView. I removed all of the auto-sizing behaviour from the scrollView.
Then, in my AppDelegate I added this:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// keep the aspect ratio constant so that the content looks good
[window setContentAspectRatio:NSMakeSize(2, 1)];
window.delegate = self;
}
- (void)windowDidResize:(NSNotification *)notification {
// size the scrollView to fill the window, but keep its bounds constant
NSRect rect = [[window contentView] frame];
NSRect oldBounds = [scrollView bounds];
[scrollView setFrame:rect];
[scrollView setBounds:oldBounds];
}
This turns the AppDelegate into the window delegate too. Fine since I've not got much logic in it. By keeping the bounds constant while changing the frame, the contents of scrollView will be scaled down smoothly.