I was testing how an existing application works on Mojave and I found strange problem with the layout. Toggle window toolbar visibility off then back on makes toolbar to appear on top of the content instead of pushing it down.
Snippet:
CustomPopUp *popup = [CustomPopUp popup];
__weak CustomRevealViewController *rev = self.revealViewController;
__weak NSWindow *window = self.view.window;
// Called when user taps in the popup view
[popup setCloseAction:^(BOOL success){
[rev removeOverlayController];
// !!! After this layout breaks
[window.toolbar setVisible:YES];
}];
[window.toolbar setVisible:NO];
[self.revealViewController showOverlayController:popup];
Any idea what could cause the problem and how to fix it?
Edit 1:
I've created a simple project here.
Steps to reproduce:
Run the project with Xcode 10 beta (Requires Mac OSX Mojave)
Press "Hide toolbar" button. This will hide the toolbar and will
update the button title.
Press "Show toolbar"
Resut:
Toolbar looks broken. It is over the controller.
Expected result:
It should work like on any other OS version. Controller's top constraint should be moved down.
Edit 2:
Maybe I found a clue in the AppKit Release Notes for macOS 10.14 beta under Layer-Backed Views section.
Views that implicitly depend on being redrawn when an ancestor,
descendant, or intersecting sibling is redrawn may not be redrawn. As
before, if a view needs to be redrawn, set its needsDisplay property
to YES. Views that return YES from wantsUpdateLayer will typically be
given an exclusive layer, even if the view's wantsLayer property is
set to NO. Apps targeting macOS 10.14 should prefer the
wantsUpdateLayer property over the wantsLayer property.
I'm still not sure how to fix it.
Edit 3:
With the official release of Mojave this is no longer an issue. Thank you I really appreciate your help.
I have a similar problem. I have a spash window without toolbar and then I fade it out and show another window with a toolbar.
The window with toolbar has broken layout in official release of Mojave (view appears beneath the toolbar). To fix it, I hide and then show again window's toolbar:
- (void)viewWillAppear
{
[super viewWillAppear];
if (_firstTime) {
_firstTime = NO;
NSWindow *window = self.view.window;
window.toolbar.visible = NO;
window.toolbar.visible = YES;
}
}
Related
Using XCode Version 9.4.1 (9F2000) I would like to dynamically allow the user to change the theme of a Mac app from Light to Dark etc, but I'm falling at the first hurdle.
I tried putting the following code in both applicationDidFinishLaunching and ViewController's viewDidLoad methods, but neither caused the theme to change to Dark theme.
NSAppearance* appearance = [NSAppearance appearanceNamed:NSAppearanceNameVibrantDark];
[self.window setAppearance:appearance];
I was unable to find an Apple sample showing how to do this programmatically. Can anyone point out what I've overlooked??
D.
I was able to get it to work by moving my code to the controller's viewWillAppear (as per sample below). Then everything is themed correctly!
- (void)viewWillAppear {
[super viewWillAppear];
NSAppearance* appearance = [NSAppearance appearanceNamed:NSAppearanceNameVibrantDark];
[self.view.window setAppearance:appearance];
}
Problem
I am having a rather big issue with the iOS7 keyboard appearance. I have a Searchbar on a UIViewController with TableView Delegation/Data Source setup (I am using the self.searchDisplayController delegates as well). I segue from this scene to a prototype tableview to show the results.
Here is the issue:
On first load I can see the keyboard being displayed when I tap into the text field of the UISearchBar. I can type and perform a search with the results being shown in the next scene.
I've added NSNotifications to view the keyboard properties in local methods keyboardWillShow and keyboardWasShown. I can see on the first scene appearance (after the view is completely loaded):
I segue to the result tableview at this point and when I navigate back and touch the text field, my keyboard shows up either fully or partially off-screen:
When I look at the keyboardWillShow notification at this point I can see that my keyboard values are incorrect:
I've researched and tried many possibilities including:
Added the following to my main view controller:
-(BOOL)canResignFirstResponder
{
return YES;
}
-(BOOL)canBecomeFirstResponder
{
return YES;
}
Configured the following in my view did load
self.searchDisplayController.searchBar.spellCheckingType = UITextSpellCheckingTypeNo;
self.searchDisplayController.searchBar.autocapitalizationType= UITextAutocapitalizationTypeNone;
self.searchDisplayController.searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
self.searchDisplayController.searchBar.keyboardType = UIKeyboardTypeDefault;
Put in standard stubs for:
-(void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
I've noticed that if I choose a Partial Curl as my segue mode, the keyboard remains accessible when I roll back to the main view controller (but then it was never fully off screen in that case). However if I move from the results tableview to a detail scene and then navigate back to the main view controller, the keyboard appears off-screen again.
Question
Is there a method I can use to intercept the misplaced keyboard so that it displays in the default location?
NB: Along these lines, I have created a NSDictionary property to hold the initial userInfo values with the correct keyboard placement. I am not sure how to reassign these values to get the keyboard to return to it's original placement.
BTW - This seems a bit of a hack to get the keyboard fixed due to a bug in IB, is there some other way that I can try to remedy the situation?
Thanks in advance for any feedback!
Solution
This was such an obscure issue that I'm sharing the solution to save the next person some effort. Like most programming issues, it turns out this one was self-inflicted. In my original iteration of this project I had turned off rotational support as I am learning auto-layout and I wanted to ease into the transition from Springs and Struts. Somehow between the start of the project and the code release I ended up with this bit of code in the Main Scenes' View Controller.
//BAD
- (NSUInteger) supportedInterfaceOrientations
{
return !UIInterfaceOrientationPortraitUpsideDown;
}
instead of returning a valid enumeration like...
//OK
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
I have a really weird issue after updating my XCode project to Xcode 5 and IOS 7.
My project is a iPad project which open views for editing in modal mode.
After update all my Modal views stop being centered after focus on a textfield (or any input field for that matter)
I open all modal views like this:
if ([[segue identifier] isEqualToString:#"add_log"]) {
MemberAddLogViewController *vc = [segue destinationViewController];
vc.selfDelegate = self;
vc.member = self.member;
}
And the seque is created with Style = Modal, Presentation = Default, Transation = Default.
If i run it on a IOS6 Simulator the modal view keeps centered, but if a run it on a IOS7 simulator it "snaps" to the left or right after focus is set in a input field with:
[self.subject becomeFirstResponder];
Anybody else having this issue?
-- UPDATE ---
After hours of this bug annoying me i tried to "redo" the viewcontroller class, and by accident i added the becomeFirstResponder into viewDidLoad and not viewDidAppear and it fixed the issue.
I had similar problem in iOS 7 in landscape mode when I was porting app from iOS6 to iOS7, my UITableViewController was centered but when method becomeFirstResponder was called in viewDidAppear and keyboard showed up the view was moving to the left or right side of the screen depending on rotation direction.
The solution was interesting, I had to run it in main thread:
- (void)viewDidAppear:(BOOL)animated {
dispatch_async(dispatch_get_main_queue(), ^{
[textField becomeFirstResponder];
});
}
and everything is working now. That may help somebody, I was looking for solution in google for few days and did not find any proper solution.
I'm just playing around with OSX app dev. I'm totally noob. I thought it is straight forward like iOS app dev. But after a few days of going at this, it seems it is not that easy.
Here's what I'm trying to do. I have a NSWindow. In it in which I put an Image Well (wth with the naming? lol) Well "Image Well", it is an NSImageView (no pun intended).
So I just want the NSImageView's frame to resize following the NSWindow's size. It's that simple.
Here's what I did that is NOT working:
NSImageView as imageView.
write the delegate method NSWindowDelegate method of NSWindow windowDidResize and windowDidResize: and just resize the framesize of imageView frame of the image view in it. Code: (The NSImageView is in a property called imageView.)
- (void)windowDidResize:(NSNotification *)notification {
// NSLog(#"resized");
NSRect zWindowRect = [[self window]frame];
NSRect zContentRect = [[self window]contentRectForFrameRect:zWindowRect];
[self.imageView setFrameSize:NSMakeSize(zContentRect.size.width,
zContentRect.size.height)];
[self.imageView setNeedsDisplay:YES];
}
This method is called (tested that with NSLog()), however the NSImageView just stays there with the original size. I checked that the IBOutlet connection is OK.
What gives? Why won't the NSImageView resize?
Ok. This is becoming a habit. Answering my own question again.
It seems that this behaviour is due to the "Auto Layout" feature of the Interface Builder.
To fix it, just disable "Auto Layout" in the MainMenu.xib. SEE HERE FOR EXPLANATIONS
In case the site expires: just click on MainMenu.xib, then go to the first tab, File, in the Utilities panel of XCode. And there should be a "Use Auto Layout" checkbox next to it. Uncheck it.
I have been coding and testing an app which uses a navigation controller, tab bar and table views together as shown in this tutorial video:
I have also coded a MapView page which shows custom annotations. This seems to work fine in every version of the simulator I have tried it on. This morning I have finally got the app running on my Ipod Touch which runs OS 3.1.3 - everything works as expected except the map does not seem to allow user interaction at all. I cannot tap on annotations, the current location or move and zoom at all.
I have been through all the settings in the Interface Builder for the mapview, and made sure that all the 'User Interaction', 'Allow Multitouch' boxes have been ticked. This doesn't seem to change anything.
Any help greatly appreciated.
The Mapview is put into the view as follows:
// Grab the maps view controller ready for loading
MapView *childController = [[MapView alloc] initWithNibName:#"MapView" bundle:nil];
childController.title = #"View on Map";
// Push the new view controller onto the stack
[self.navigationController pushViewController:childController animated:YES];
[childController release];
childController = nil;
I've also tried running the view in a modal view controller just to see what would happen. The view was shown and any interaction didnt seem to work - with the exception of a small section at the bottom where I made the view itself slightly shorter so it would fit in above the tab bar. This section seems to have another map underneath my view which DOES respond to user interaction. So there is a 1cm or so block which does move - my view seems to stay static on top of it, though.
The view underneath does not appear to have any annotations or the current user location.
Ok I've solved this one:
In the mapview.m file where I set up the view and load the annotations, within the viewDidLoad function I had the following code:
- (void)viewDidLoad {
// More code before this..
[mapView addAnnotations: eventPoints];
// This is causing the problems on the ipod touch.
// The view is added ON TOP of the first map..
//[self.view addSubview:mapView];
self.view = mapView;
// More code after this..
}
Where mapView is
IBOutlet MKMapView *mapView;
Adding a subview on top of the current view didn't want to work. Actually setting the view to be the new updated view with annotations seems to work fine. It's still strange that the simulator would work and not the device in the first place though.
Hope this helps someone.