I have implemented a simple Table View Controller with a Search Display Controller dragged out via Interface Builder. I then enabled refreshing so that a Refresh Control is visible when the user pulls down to refresh.
The problem is, the spinner is visible on top of the search bar when it should lie underneath it.
I know the cause is the Minimal Search Style. If you use the default Prominent style, the issue doesn't exist.
When you slowly pull down you'll see the first line appear overtop the search bar like so:
If you keep pulling it does show up in the location you expect, but if you push the view back up while it's still refreshing you'll see the spinner on top of the search bar like so:
As soon as you push it up so that the spinner touches the first section header, the spinner immediately disappears.
This is how it is supposed to look, like it does in Mail - underneath the search bar:
I tried to fix the problem by simply making the spinner lie underneath the search bar so that it would never appear overtop, but that did not work. Oddly enough, that code caused the spinner to not be visible in the gray area above the table and if you push it up it appears overtop the search bar - exactly opposite of what I would expect. Here is that code:
self.refreshControl.layer.zPosition = self.searchDisplayController.searchBar.layer.zPosition - 1;
How can I prevent the spinner appearing on top of the search bar when using the Minimal style?
To workaround this bug for UISearchBarStyleMinimal, you have to set backgroundImage property with any image. Only if background image is set, layout behave correctly.
private extension UISearchBar {
private func setBackgroundColorWithImage(color: UIColor) {
let rect = self.bounds
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextFillRect(context, rect);
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.backgroundImage = image // here!
}
}
This seems to be a bug with the Minimal Bar Style. If you set it to Prominent you won't experience the issue. If you use Prominent and try to remove the background, you'll also experience this issue. The only workaround I've found is to try to mimic the Minimal style with the Prominent style applied.
Move the refresh control behind the search bar when you set it up.
refreshControl.layer.zPosition -= 1
So if it helps anyone i had the same problem and a fast solution is adding the refreshcontrol as a subview of self.view instead of tableheaderview. This will add the controller above every thing else and at leas you'll be able to see it. On the other hand i believe you could fully corrected y setting it under the correct layer.zPosition. But i haven't had time to fully correct it.
[self.view addSubview:self.refreshControl];
Related
I'm working on an iBooks type of app for iOS 5 and have everything working except for the background image. Specifically in landscape mode.
Up to this point I've been using:
UIImageView *background = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"book.png"]];
[self.view addSubview:background];
[self.view sendSubviewToBack:background];
If I do this on the RootViewController, the spine obviously doesn't show through the page view controller's view and if I use this inside the page view controller class, it removes the ability to use CGRectInset to specify where the pagecurl should begin.
I'm sure this is probably something pretty basic, but I've looked through every book that I have as well as Google, and I don't see this covered anywhere. Any help would be appreciated.
Thanks
You will need to use a background image for your book and then use a right page image for the right side and a left side image for the left side. These will need to align and match up with the full book background image. You can use a UIImageView for all three. Keep in mind that the left and right page images will need to be perfectly square (except for the spine) with no transparent area, otherwise you get a weird shadowing effect. Also make sure all background colors are set to clear.
So you will have this hierarchy:
Root View (full screen bounds)
Book Background View (However big you want)
Page View Controller (A little smaller than the book background view, you'll have to play with this until everything looks right)
Left page view controller
Image of left page and whatever else goes on the page
Right page view controller
Image of right page and whatever else goes on the page
I hope this makes sense.
I have setup my project to mimic the SideMenu example project to the best of my abilities, but the background image for the sideview is
not displaying properly. I would like to only have underlines under the cells that I setup, not have a title bar and have the background image stretched across the sidemenu, not repeated several times. I am fairly weak on storyboarding, so if there is any info you need to help with this, please let me know. I have gone through all of the attributes settings I could and can't seem to find anything else helpful.
I have included a picture of the look I want to achieve, my current app and my current tableview in the storyboard interface
Below is my code showing how I am setting up the side menu background image.
SideMenuManager.default.menuLeftNavigationController = storyboard!.instantiateViewController(withIdentifier: "LeftMenuNavigationController") as? UISideMenuNavigationController
SideMenuManager.default.menuAnimationBackgroundColor = UIColor(patternImage: UIImage(named: "sidemenubackground")!)
// Enable gestures. The left and/or right menus must be set up above for these to work.
// Note that these continue to work on the Navigation Controller independent of the View Controller it displays!
SideMenuManager.default.menuAddPanGestureToPresent(toView: self.navigationController!.navigationBar)
SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.navigationController!.view)
I am trying to achieve this look. My current view repeats the background image repeatedly, has a title bar on the top and has underlines under nonexistent cells:
This is what my side menu looks like currently:
Here is what my tableview looks like in the storyboard currently:
Built-in Photo application fades in/out navigationBar when you tap on an image . This way Photo app allows to see it full screen.
How does it do this (fade efect)?
As I understand navigationController?.navigationBar.alpha doesn't work anymore (so you can't animate it this way).
Sharing all my finding.
Complain mode on
Frankly, I feel half pissed/like a dummy that I had to fight a good day to implement simple thing existing in Apple app.
Complain mode off
First of all here is some context. I am working with navigationBar which are provided by navigationController (vs just standalone bars which are manually dropped in your view)
There are several approaches which I found. I will mention all of them (even if I had no success using them)
1) Animate change of alpha of navigationBar
UIView.animateWithDuration(0.1, animations: {
navigationController?.navigationBar.alpha = 0
}, completion: nil)
#rmaddy mention here that it works for him. However, I believe he has a standalone bar (vs a bar managed by navigationController).
I used a tool Reveal to check UI hierarchy and found couple of things.
- There is a navigationBar which is hidden (and navigationController?.navigationBar is referencing it). So you can change alpha to your hearts joy, but these changes won't be visible.
There is however another navigationBar . I assume it's referenced in some private members of navigationController (let's call it private navigationBar). It's visible and that's what is displayed at the top of your view.
2) Use setNavigationBarHidden:animated:
This is a standard way to hide/show navigation bar. It's animated different way (it slides/up and down). However, if it's ok for you, just go with this is, because it's simple and clean.
navigationController?.setNavigationBarHidden(true, animated: true)
Additionally you can wrap it in UIView.beginAnimations, UIView.commitAnimations to animate it together with some other stuff (to make it smoother)
3) Animate change of alpha of private navigation bar.
This worked for me:
let privateNavigationBar = self.superview?.superview?.superview?.superview?.superview?.superview?.subviews[1]
UIView.animateWithDuration(0.1, animations: {
privateNavigationBar.alpha = 0
}, completion: nil)
I am going way up through the hierarchy to get a view which contains private navigationBar (which is second subview for that view).
However, this approach has multiple downsides:
I believe # of superviews? depends on your app hierarchy (vs you are using split view and so on). I think you can generalize or may be you just walk the whole hierarchy to find non hidden UINavigationBar to solve this.
I have a feeling that Apple may frown at this (your app be not accepted to AppStore)
4) Make navigationBar transparent and set background image to be transparent and change alpha channel on it.
I can't find where I read about this idea. There was couple of mentioning.
There is Apple example app which shows how to customize NavigationBar, including making it transparent.
It's interesting that this example app works for me (the navigation bar is transparent in it). However, when I tried this code in my app it didn't work (I still didn't figured out what is going on with this). As usual there are bunch of variables (may be something in Info.plist, also they subclass NavigationController, also may be something in view hierarchy)
5) Adding standalone navigationBar
You can hide a bar provided by navigationController. Add your own to the UIView, wire it to #IBOutlet and use alpha animation on it (most likely that's what #rmaddy was referring too).
I checked and this is work.
This approach is used in this tutorial.
However, it has a downside:
I believe it won't handle well rotation, increase of statusbar height while call or GPS
Each time when I see a code like this (written in the article) I know that there will be problems with resizing: CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 64.0)
You can potentially replace it with constrains. I went this route, but stumble upon some issues.
6) Other methods
I saw two more methods. I don't know whether they will work or what will be downsides:
One of them in this question: How to hide/show status bar and navigation bar by fading in/out at the same time like the Photos app in iOS 7?
And this answer: https://stackoverflow.com/a/18063898/422080
I have a UIActionSheet and when it displays it darkens the main view behind it, I am under the impression this is default behavior for an action sheet. My question is, how do I override this behavior to leave the main screen the same tint as it normally is? I'm assuming I do something like:
mainView.alpha = 1f;
Or something...I can't remember if alpha needs to be maxed or 0 to leave a screen with the same coloration/transparency. Anyways, if that is correct where should it happen? My action sheet is being called in place of a keyboard for a UITextField.
Thanks in advance.
You can't change this behavior. UIActionSheet is actually presenting a whole new view overtop of your view. It's this additional view that adds the tint. There is no API to change this.
Your best solution is to implement your own custom equivalent to UIActionSheet so it does exactly what you want.
My app needs to save an image to disk. I do this in a separate thread, so the UI is still responsive, BUT, I do not want the user to add a new image until the first one is saved (about 1 second.)
At the moment, I'm disabling the 'take another picture' button and greying it out, but I'm wondering if there is a method that will disable the whole view, greying out the buttons and darkening the background, like what happens when a UIActionSheet is presented.
I've looked through the UIView docs and don't see anything like this, but it seems like such a useful pattern that is frequently used by Apple that I figured I'd ask, just in case there was such a thing.
Obviously I could do it manually, but why reinvent the wheel if its already part of the API.
TIA: John
set whatever view (main view, subview, etc.) you want to appear disabled to
view.userInteractionEnabled = NO
and also
view.alpha = 0.3f
and maybe even
view.backgroundColor = [UIColor grayColor]
to boot. These last two can be animated, b.t.w.
Present another view with the shadow and the gradient etcetera over this view thus giving it an effect of graying out with shadows. You may even create an image if you know your photoshop. Just show that image on a UIImageView over this view to be blocked. Give the image some nice translucency, shadows etc etc