Remove NSWindow content view - objective-c

I set the content view for the following window and now i want to remove that content view and set it to something else. I tried just setting the content view to another view and that did not work, how can i just remove it? thanks!
controlFilterBox = [[MoveFilter alloc] initWithFrame:helpWindow.frame];
[helpWindow setContentView:controlFilterBox];
[controlFilterBox release];

You can't remove the contentView (i.e. set it to nil). The window requires a view. You probably can get what you're trying to do by calling [controlFilterBox setNeedsDisplay:YES], but I typically recommend that rather than messing with contentView itself, you make the views you want to swap to be subviews of contentView. Then you can just swap them around as normal views with removeFromSuperview and addSubview:. It's just often easier than dealing with a special view like contentView.

Related

How to show a uiview alway on top?

I want to show a logo UIView always on top when the app running,
I know there is a way to do that,add same UIView to every UIViewController,
but I think this is not the best way to do that.
when i have lot of pages,and modify the logo UIView,must modify it every page.
Did someone have better way to do this?
thanks.
look like this:
Since you only every have one window per app, and view's don't have levels, you have to make sure that view stays on top of the hierarchy, no matter what. One relatively easy way is to add it directly to the window above the rest of the interface (the navigation controller):
In applicationDidLaunch:
// After the main navigation controller or tab controller has been added
// either programmatically or in the xib:
UIImage *logo = [UIImage imageNamed:#"logo.png"];
UIImageView *logoView = [[UIImageView alloc] initWithImage:logo];
[self.window addSubview:logoView];
Actually, I think that (a) creating a subclass of UIView that shows your logo and has all the necessary setup in it and then (b) adding this subclass to each view controller is the cleanest and most manageable way to do this.
The reason I prefer this method over adding the view to the window is because if you ever have a view that you don't want to show the logo, you won't need to show and hide something you added to the window. Also, adding directly to the window may cause rotation challenges on certain iOS devices in my experience, depending on what you're doing.
Also, to make sure your logo view is always on top of the view hierarchy, you can do two things:
If the view already exists, you can bring it to front using [UIView bringSubviewToFront:]
[myParentView bringSubviewToFront:myLogoSubview];
If you are creating the view, it will be on top when you add it with [UIView addSubview:]
// Set up myLogoSubview first here with alloc+init, etc.
[myParentView addSubview:myLogoSubview];`
It looks like in your image you would replace myParentView with self.view and myLogoSubview with the view you're looking to keep on top, but this is just my assumption based on your image.

How to make current view a scrollview? iOS / Objective C

I have a view (that is actually part of a UINavigationControllers view) that i want to make a scrollview.
how do i do that?
could i do something like this:
UIScrollView * content = [[UIScrollView alloc] initWithFrame:self.view.bounds];
self.view = content
(obviously that doesn't work, but is there a way to do it like that)?
Yes, it is, you have to implement delegates, and set the contentSize. The best tutorial on scrollViews ever I found is:
http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
You are on a good way!
You can create the scroll view programmatically like you do and then add the existing view as a subview of this new scroll view, examine addSubview: (which works on all UIViews and subclasses like UIScrollView as well). I won't say this is the solution or even a clean one for that matter, but if you read about addSubview: you can at least figure out how to have a view live inside a scroll view...

Alternating between several NSViews

What I need may be pretty basic, but I'm definitely not sure as to how to proceed (I've done that before but none of my choices seem that Cocoa-friendly).
Ok, let's say we've got 2 NSViews - one next to the other:
The one on the left serves as a menu.
The one on the right will show a NSView (from a different XIB perhaps?) depending on the selection on the menu.
My questions :
How should I go about loading the different NSViews into the rightmost NSView?
How do I make sure that the subview (the one currently active) is properly resized when the window is resized?
rdelmar's solution should work, but another approach, which may be simpler, is to use an NSTabView to handle switching between the content views. You can hide NSTabView's tabs using the settings pane in interface builder, or by calling [self.tabView setTabViewType:NSNoTabsNoBorder]. I'd probably use a table view for the left side. When the user selects a row, you do something like:
-(void)tableViewSelectionDidChange:(NSNotification *)notification
{
[self.tabView selectTabViewItemAtIndex:[self.menuTableView selectedRow]];
}
The NSTabView can/will take care of properly resizing its content views as long as you've set up its and its content views' autoresizing masks (springs and struts) properly.
You should be able to create a custom view in IB that looks like your yellow view, and set its resizing behavior to expand in both directions with window resizing. Then, when you get your new view (by just referencing one you already have or loading a new xib), add it as a subview of the custom view, and set its frame to that of the custom view. I think that views resize their subviews by default, so it should resize correctly with the custom view.

Using a patternimage for a View inside an NSScrollView

I have a quite big problem, I am really not able to solve myself.
The result should look like this:
This image was made with photoshop and is part of the interface I try to build.
In the middle you see something, that should be a list of projects, you should be able to scroll, if it the list is bigger then the view.
So I am making a scrollview like this: (for some reason I cannot do this in the interface builder and want this to work programmatically)
NSScrollView *projectsListView = [[NSScrollView alloc] initWithFrame:NSMakeRect(15, 2, 801, 588)];
[projectsListView setHasVerticalScroller:YES];
Then I create the content view and set a pattern image as backgroundcolor:
NSClipView *contentView = [[NSClipView alloc] initWithFrame:NSMakeRect(0, 0,
[projectsListView frame].size.width, [projectsListView frame].size.height+(98*2))];
[contentView setBackgroundColor:[NSColor colorWithPatternImage:[NSImage imageNamed:#"BoxLineBackground"]]];
[contentView setDrawsBackground:YES];
Then set the view as document view:
[projectsListView setDocumentView:contentView];
Should work, right?
However the content view gets clipped and looks like this while scrolling:
I tried this to fix it, but it does nothing:
[[projectsListView documentView] setCopiesOnScroll:NO];
I also tried this, but it causes the contentview not to scroll at all.
The image stays the same, but I can move the scroller normally.
[[projectsListView contentView] setCopiesOnScroll:NO];
If I try to set the contentview with setContentView: instead of using setDocumentView:
it may work, but the scroller is gone, so it is also not working correctly.
I would really like to use the patternimage method, because I cannot tell how long the list will be. It depends on the user.
An additional problem then would be to get the whole thing rounded, but that does not matter that much. I tried to use a transparent border image and to overlay the NSScrollView with it using an NSImageView, but again this causes corruption, because it clips and moves the overlaying parts of the image view together with the content of the scrollview.
Anyone having an idea, how to achieve this?
Thanks
Rather than re-inventing the wheel, this interface should be implemented with a view-based NSTableView. The table cell UI could then be created in Interface Builder and you could control the background of the cells using the various NSTableView delegate methods. NSTableView will handle redraws upon scrolling correctly.
To handle the pattern color, just make the background of your cell a custom subclass of NSTableCellView and implement your pattern drawing code.
Regardless of all this, the problem you are having is due to an NSScrollView drawing optimisation. You can turn this off by calling [[yourScrollView contentView] setCopiesOnScroll:NO] on your NSScrollView instance. You can also set this in Interface Builder, just un-check the Copies on Scroll checkbox.
I fixed the problem by setting the Background Color on the NSScrollView instead on the NSClipView.
I though the background would be static in that case and I need to set it for the content view for that reason, but it works pretty well and does scroll together with the content view.
And thanks for Rob Keniger's answer. I will probably try this out.

Objective C: Can I set a subview to be firstResponder?

I have a situation whereby I am adding a view from another viewcontroller to an existing viewcontroller. For example:
//set up loading page
self.myLoadingPage = [[LoadingPageViewController alloc]init ];
self.myLoadingPage.view.frame = self.view.bounds;
self.myLoadingPage.view.hidden = YES;
[self.view addSubview:self.myLoadingPage.view];
Is it possible to set 'self.myLoadingPage' to be the first responder? This is the case whereby the loadingpage view size does not cover the entire size of the existing view and users can still interact with the superview (which is not the desired behaviour). I want to just enable the subview in this case.
When I had a similar problem, I made an invisible UIView that covered the entire screen, I added the large invisible UIView on top of the main view and made the loading view a subview of the invisible UIView.
The simplest solution is to override hitTest method in your loading view to return TRUE. This top view is first in the responder chain, the hitTest method gets called which NORMALLY returns TRUE if the point is within the view and will therefore be handled, returning TRUE regardless means you get the touch event and effectively block the message being resent to the next responder.
Interesting question. I found a similar post with a quote from the Apple Developer Forums on this issue:
To truly make this view the only thing
on screen that can receive touches
you'd need to either add another view
over top of everything else to catch
the rest of the touches, or subclass a
view somewhere in your hierarchy (or
your UIWindow itself) and override
hitTest:withEvent: to always return
your text view when it's visible, or
to return nil for touches not in your
text view.
This would seem to indicate there isn't a terribly straightforward solution (unless there was an API change regarding this made after October, 2010.)
Alternatively, I suppose you could go through all the other subviews in your superview and individually set their userInteractionEnabled properties to NO (but that would probably prove more cumbersome than the quoted solutions).
I would love to see other ways to allow this.