NSView (Content View) as firstResponder - objective-c

I have a Content View that I use in my preferences nib.
I use a method to change the font of a NSTextView in my app.
This Content View has to be set as firstResponder to get messages from my changeTextFont: method, but since it's not a window it doesn't have a firstResponder. As a result, it does not change the text font at all... does anyone have a workaround for this ?
Thanks a bunch guys.

I could make the sample project work without specifying [self window] as first responder. What I did was:
in (void)changeTextFont:(id)sender, I replaced the statement:
[[self window] makeFirstResponder:[self window]];
with lines:
[[NSFontManager sharedFontManager] setAction:#selector(changeMyFont:)];
[[NSFontManager sharedFontManager] setTarget:self]; //-- this seems to be not mandatory, but I mention it because your case could be different
I renamed changeFont: to changeMyFont::
- (void)changeMyFont:(id)sender
{
With these changes, the font is correctly updated in the example content view.
I don't know if it will work for you, because in the end you are trying to use this code in a different context, but I hope that it will. I would suggest you to first try and modify the sample project so that you can get confident with my solution and then move it to your project to check whether it also works there.

Related

Button does not react

I have a strange behaviour with an NSButton. It works normal until I do so voodoo somewhere else in my app. Right then the button does no longer react on click events. It still looks normal (so not disabled). It just does not do anything when I click it. Any idea where I should look in the properties of NSButton that might have been changed accidentally? (Quite sure I did not touch the button itself.)
Ensure your button is in a 'touchable' zone in its superView. I mean It have ro be placed inside it superView bounds (If not, you can see It, depending on Clipping properties, and you can't interact with It). In order to check it, set a color to your container view.
Also check userInteraction is enabled...
Hope It helps.
If your button is just not giving the animation, it might be an Xcode bug. I had a similar problem before, and I filed a bug, and it got fixed on the next Xcode version. Check out my SO question. Toolbar bar button item not working properly in SplitViewController
If you really need to give it an animation, you could probably do it in code with something like this. Please note that this is untested so it may not work, or you might need some fixing, but you get the idea :)
- (IBAction)buttonAction:(id)sender {
self.button.titleLabel.textColor = [UIColor lightGrayColor];
// Action
self.button.titleLabel.textColor = [UIColor darkTextColor];
// Or with delay
[self performSelector:#selector(changeButtonColor) withObject:nil afterDelay:0.1];
}
I figured it out. The button opened a transient popover. In order to close this popover due to an action I had coded
view.window!.orderOut(self)
After replacing it by
view.window!.performClose(self)
the strange effect was gone. I'm not sure, but this looks like a bug in the Swift runtime. I'll report it and see what comes out.

Custom UIButton background image showing in iOS 6 but not iOS 5

I set the button background in the interface builder, but that wasn't showing up so I set it programmatically. All (but one button... why?) shows on the simulator but never show on a device.
I get this output:
Could not load the "gray_button.png" image referenced from a nib in the bundle with identifier "com.example.ios"
This is the code:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.getMyTripButton setBackgroundImage:[UIImage imageWithContentsOfFile:
[[self getFullPathname] stringByAppendingPathComponent:#"images/gray_button.png"]]
forState:UIControlStateNormal];
[self.popupButton setBackgroundImage:[UIImage imageWithContentsOfFile:
[[self getFullPathname] stringByAppendingPathComponent:#"images/gray_button.png"]]
forState:UIControlStateNormal];
[self.viewOurPackages reloadData];
}
I have also tried replacing imageWithContentsOfFile with imageNamed and both yield the same results.
I have added the images directory in my Project > Targets > Build Phases > Copy Bundle Resources, but I think this is where it all starts to go wrong and I can't figure out why. Possibly because it's a directory?
I would like to point out that I have double and triple checked that it is not a capitalization/case-sensitive issue.
UPDATE: I have solved the one button not showing. It would seem that real issue is that the images show on iOS6 and NOT on iOS5.
What worked for me was one (or a combination) of the following 3 things:
Make sure your image file is formatted correctly. Sometimes png files need a little coercing. (I think this specifically was my problem)
Make sure your button is of type Custom in the Interface Builder or UIButtonTypeCustom.
If you are setting the image in Interface Builder and it's still not showing, set it explicitly in the code using [button setBackgroundImage:image forState:UIControlStateNormal] (or [button setImage:image forState:UIControlStateNormal] depending on which one you need.
If you are adding a folder to the copy bundles, then instead of referencing the file as gray_button.png, you should reference if from code or xib You will have to include the directory in the name too such as directory/gray_button.png
Steph,
If you used #synthesize for the button in the .h file, then getters and setters are automatically created. Thus (this is a longshot and just a thought) having the name getMyTripButton could be confusing Xcode somehow. Try renaming the variable?
As far as the image not loading... for one of the buttons and not the other... da faq? Is this the only places that gray_button.png is getting called? (for example, you aren't modifying that button somewhere else that may tell it to use that image again). Have you tried putting it in the same directory as the nib that is using it? are you sure getMyTripButton is properly tied from the nib to the code?
Last thing I can think of for now:
you said
I set the button background in the interface builder, but that wasn't
showing up so I set it programmatically. All (but one button... why?)
shows on the simulator but never show on a device
do you have popupButton's background image also set in the nib/interface builder? if you already have it set there and are setting it again here, it may be that it isn't really getting set in the code at all and is just using what is in interface builder which could explain why getMyTripButton may not be showing up/showing the background image.
If I think of anything else that could be causing the issue i'll edit this post. Good luck, and hang in there.

Howto identify modalForWindow using NSViewController

I have one NSWindow (mainwindow) for my OSX NSApplicationDelegate. The NSWindow also holds several NSView's where the content is set using NSViewControllers. Currently I ran into a problem when I wanted a NSPanel, a sheet, to drop down from the top of one of my NSViews (not from the top of my app). I wanted to use the code:
[NSApp beginSheet:self.loginSheet.window
modalForWindow:self.view.window
modalDelegate:self
didEndSelector:nil
contextInfo:nil];
The loginSheet is a subclass of NSWindowController which loads the xib file using:
loginSheet = [[sheetWindowController alloc] initWithWindowNibName:#"loginSheet"];
However, I run this code from my NSViewController and my self.view.window is always nil. My NSView seems otherwise correctly initialized and works fine, but the drop down of the sheet does not work as my modalForwindow (self.view.window) is nil. If I use the code:
[NSApp beginSheet:self.loginSheet.window
modalForWindow:[[NSApplication sharedApplication] mainWindow]
modalDelegate:self
didEndSelector:nil
contextInfo:nil];
it works like a charm. But from all my searching to find an answer to my problem it seems that this working approach is a big no-no since it blocks the entire app from any response. I wanted my sheet to be linked to one of my NSViews' but I dont see how I can do this given that the app only have one NSWindow? Am I not doing something that makes my self.view.window stay nil? Is there a good way for me to find the parent window of custom views? If you have any suggestions for how to solve this problem or can give me a hint on what I am doing wrong that would be greatly appreciated.
Thanks! Cheers, Trond
You should have a look at the "Positioning Sheets" section of "Introduction to Sheets" docs. It explains how to make a sheet appear from somewhere other then under the window's title bar using window:willPositionSheet:usingRect:

Force the keyboard to become visible and stay visible in view

I want to have the virtual keyboard appear in my view on load and I want it to say visible for the lifetime of the view. There is a text field and I treat as the primary control for this view.
Initially, I called [self.textField becomeFirstResponder] in -viewWillAppear: following advice I've gotten here. Then, I came up with a different idea: I overloaded UIViewController's -becomeFirstResponder.
- (BOOL)becomeFirstResponder
{
if (self.primeResponder)
return [self.primeResponder becomeFirstResponder];
return [super becomeFirstResponder];
}
I'm not seeing any hidden problems with this, but then again, no one recommends it either. Am I missing something? Is this a bad approach? Please help.
In reviewing my old question, I thought now would be a good time provide an answer to this.
It works and does not have any major drawbacks.
I've had good luck with this method except in a peculiar circumstance. I used this to set a text field in a table view cell as the prime responder. In iOS 6, it didn't load the keyboard or highlight the textfield when the view was pushed onto the navigation controller stack.
See In iOS 6, -[UITextField becomeFirstResponder] doesn't work in -viewWillAppear: for my solution to that problem.

How to hide or remove the UIwebview when a action is done?

I have two IBActions. In one action I am loading the UIWebview to display a PDF File from my bundle. On clicking the other button the whole UIWebView should get removed from superview.
I have tried using:
[webview removeFromSuperview];
and
webview.hidden=YES;
Neither of these are working. They are hiding my UIWebView for a second, but then it appears again.
Is is
I have created UIWEBVIEW programatically and added the UIWebvieWDelegate in the interface file. But when initializing the UIWebView I didnt set webview.delegate=self; Is it the problem?
have you connected Referencing Outlet to the class's #property in the Interface Builder?
If you don't do it, it would be the a possible reason why you cannot reach the UIWebView in your source code. for your sake, you should check the pointer of webview, if it is nil chronically, there is 100% you have not connected them each other.
I was trying to make a thing like this. The solution that worked for me was to add UIview object as subview to view with the frame of webview and bringing it to top.... When u want to make uiwebview visible, just remove that uiview object from superview.
OK, it seems old question, but also i can see there are almost thousand people have view it, and may have the same problem. so my answer for anyone my have the same issue in the future.
I just been doing something smiler and want to hide the web view when at a certain action.
I have tried the following
-(void)viewDidLoad
{
[super viewDidLoad];
process = [ProcessingData new];
[DetailView setHidden:YES];
DetailView.hidden = YES;
[DetailView removeFromSuperview];
self.DetailView = nil;
}
however it is still not working, as i have few labels in the WebView which are don't disappear when the view load, when I looked at the "StoryBoard" i notes that the labels are not subview of the
can u see the hierarchy of the libels under the WebView, they are subview of the main view, where they suppose to be same as the table view hierarchy
so in may case the WebView is hiding but the labels are not as they are not a part of the Webview.
how to sort this problem, if you really don't need web view use the normal one, otherwise you have to hide all the labels in that view. hope thats helpe
I don't know obj-c but still posting a solution that worked for me in swift. basically you have to use the main thread to remove the webview.
DispatchQueue.main.async {
print("\nremoving webview\n")
self.myWebView.stringByEvaluatingJavaScript(from: "document.body.innerHTML='';")
self.myWebView.removeFromSuperview()
}