I asked the following question one hour ago:
Rotating NSImageView cause the NSImageView to scale
I found the solution to a rotation issue by rotating the NSView:
[self setFrameCenterRotation:-priorResult];
[self setFrameCenterRotation:rot];
[self setNeedsDisplay:YES];
This works just as I want it but when I try to move the NSView by setting the frame:
[self setFrame:CGRectMake(prect.xPos, prect.yPos, prect.w, prect.h)];
The frame won't move correctly. I read about CALayer and Core Animation, but I don't understand it, does anyone have a simple solution for my problem?
Related
I'm trying to get a transparent background on my NSTableView, however, it seems as though the NSClipView nestled inside the NSScrollView is causing weird background problems, where it seems it's redrawing the background of the main NSView inside the NSClipView.
I've done all this in an attempt to remove it, but it's just not happening:
[[self.scrollView contentView] setCopiesOnScroll:NO];
[[self.scrollView contentView] setDrawsBackground:NO];
[self.scrollView setDrawsBackground:NO];
[self.scrollView setCopiesOnScroll:NO];
Any help would be greatly appreciated.
Regards,
Mike
Found the answer. When creating the background image in the NSView subclass, change the bounds of the drawInRect from dirtyRect to self.bounds. Works a treat.
After I overlay an application over my previous application, I go back to previous application and encounter a few errors:
certain components have disappeared
only way to make the components visible is to resize the window
that seems to redraw the whole canvas.
Weird thing is that there are only a couple of components and drawn images that are missing
It doesn't always happen but only a couple of times
I haven't found a solid way to reproduce the problem.
Anybody have an Idea why this is happening?
I experienced exactly the same issue (view was updated correctly only after resizing), except that I've used OpenGL drawing in OSX game.
My problem was solved by adding this:
GLint vblSynch = 1;
[[self openGLContext] setValues:&vblSynch forParameter:NSOpenGLCPSwapInterval];
in my custom NSOpenGLView init method.
Then I've implemented:
- (void)drawRect:(NSRect)rect
{
[self destroyFramebuffer]; // glDeleteFramebuffers..
[self createFramebuffer]; // [super prepareOpenGl], glGenFrame(Render)Buffers, bind buffers, etc
[self drawView]; // [[self openGLContext] makeCurrentContext], make some drawing, [[self openGLContext] flushBuffer]..
}
like this.
After these changes, when window gets focus it redraws itself (without any resizing stuff :) ).
Hope this helps!
I have a view (it's the view that is zoomed in a scrollview) that I am trying to make only stretch in the x direction when the user pinches or double-taps to zoom. This view is being constantly drawn on: up to 10 times per second, using Core Graphics to draw a graph.
So I override setTransform like so:
- (void)setTransform:(CGAffineTransform)newValue;
{
CGAffineTransform constrainedTransform = CGAffineTransformIdentity;
constrainedTransform.a = newValue.a;
[super setTransform:constrainedTransform];
}
And this generally gives me the behavior I want, except for one big problem. When the view is being drawn on very often and the user double taps to zoom in, the whole view will often just go black. This happens very rarely if I don't override the above method (although it still does happen once in a while). Also interesting is that when the user zooms using a pinch gesture, this does not happen. This is the function triggered by the double tap:
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer
{
CGRect frame = [[self tiledScrollView] frame];
float newScale = [[self tiledScrollView] zoomScale] * kZoomStep;
CGRect zoomRect = [self zoomRectForFrame:frame withScale:newScale withCenter:[gestureRecognizer locationInView:[[self tiledScrollView] tileContainerView]]];
[[self tiledScrollView] zoomToRect:zoomRect animated:YES];
}
And the pinch gestures are just handled by UIScrollView's stock pinch recognizer. One thing that does bother me about the above function is that zoomRect is scaled in both the x and y directions even though my view only scales in one direction. I have tried scaling zoomRect in only the x direction and then calling zoomToRect, but then the graph won't zoom.
So it seems that UIScrollView's pinch recognizer and my double tap recognizer scale the view in two different ways, and only the pinch recognizer's way works with my code... Also, this problem becomes very rare when the drawing rate is slowed, and nonexistent when there is no drawing going on. I've tried using queues to make drawing and zooming sequential but I haven't had much luck with that. I suspect that zoomToRect and other zooming methods may dispatch tasks off to other threads or whatever so I don't think they can be sequentialized that way. But is this something I should look into more?
Any help would be greatly appreciated. I've wasted days trying to fix this already -_- Thanks
I am trying to use this bit of code:
[[myUIView layer] addSublayer: layer];
[myScrollView addSubview:myUIView];
[layer addAnimation:[self imagesAnimation] forKey:#"images"];
What I am doing to do is taking a layer that will later get a CAKeyFrameAnimate and placing that layer inside a UIView so I can use the standard view function:
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return myUIView;
}
But I digress... Then placing the UIView & layer inside of a UIScrollView so I get all of that good UIScrollView functionality.
At least this is how I believe it to work atm.
Hoping for some help currently it just shows a white screen but when I replace the first to lines with:
[[myScrollView layer] addSublayer: layer];
I get an animation that plays but now zooming goodness.
Any help would be appreciated.
EDIT: In summary what I am trying to do is is have a CAKeyFrameAination inside of a layer inside of a UIView inside of a UIScrollView. The reason for this packing is because I need an Animation that can stop start and zoom in. the First three lines of code produce a blank white screen but when I replace them with the last bit where I'm putting the layer on myScrollView it plays but as expected I get no zooming as
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
is expecting an UIView and doesn't work if I tell it to expect a layer.
Hope this is clearer.
I thought I was adding the UIView in via code but apparently I needed to add it in via the IB and link it up to the code.
I am looking for a perfect solution to set a background image for a window in a cocoa application. I haven't found a solution to this, I am new in objective c, so please anyone help me...
A window in Cocoa has a root-level view called the "content view". This is the view that contains all the others in a window. By default, it's just a plain, blank NSView. But you could easily create your own custom NSView subclass, override the drawRect: method to draw your background image, and use that for your custom view.
However, it might just be easier to use a plain old NSImageView. The advantage of this is that you can set, for example, autosizing behavior to keep the image pinned to one corner (try this with Installer.app by resizing the installer window). You would also be able to make it semi-opaque so that the background shows through a bit. (Again, I'm thinking of Installer.app; your app could be totally different)
Hope that gets you going in the right direction!
Michael Vannorsdel suggests sublassing NSView for the purpose, and I quote:
You'd really be better off making an
NSView subclass and having it draw
the image you want in drawRect:.
- (void)awakeFromNib
{
myImage = [[NSImage alloc] init....
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)rect
{
NSSize isize = [myImage size];
[myImage drawInRect:[self bounds] fromRect:NSMakeRect(0.0, 0.0,
isize.width, isize.height) operation: NSCompositeCopy fraction:1.0];
}
Read that whole thread on cocoabuilder, it's quite instructive.