Scroll VIew and MBProgressHUD - ios

I am new to iphone development. What i have done here is, loading a view with a scroll view on which I m showing pictures.
I have got a basic navigation controller in the app..
Now, during the loading of picture if the picture is not fully loaded i want to add a MBProgressHUD..
I m using the following code for that but, not able to see the it infront of the scroll view although the hud is added on the view as i am unable to move the scroll View..
HUD = [[MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES] retain];
[[self.view superview] bringSubviewToFront:self.navigationController.view];
Any Suggestions please... Thanks for your help..

Assuming when you do:
HUD = [[MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES] retain];
You get an UIImageView, you can do something like:
[scrolView.view addSubView HUD.view];
HUD.frame=CGRectMake(x,y,width,height) //So you can specify where you want your image.

Building on RuiAAPeres's answer, here's some more complete code in Swift:
let frameHeight = self.tableView.frame.size.height
let frameWidth = self.tableView.frame.size.width
let hudHolderYCoord = frameHeight / 4 + self.tableView.contentOffset.y
let hudHolder = HUDHolderView(frame: CGRectMake(0, hudHolderYCoord, frameWidth, frameHeight / 2))
hudHolder.backgroundColor = UIColor.clearColor()
self.view.addSubview(hudHolder)
let hud = MBProgressHUD.showHUDAddedTo(hudHolder, animated:true)
let label = "Just a sec.."
hud.labelText = label

Whether its scrollview or tableview, you can refer the following link
MBProgressHUD at center added to tableView or scrollView

Related

Need to set pop up at top instead of inposition centre

I just followed one project for use pop up.But in that project the pop up view position is in centre.But i need to show pop up at top (i.e should show up in top with use half space of navigation bar)github project
I use UIViewController+ENPopUp.m UIViewController+ENPopUp.h JWBlurView.h JWBlurView.m files.I have changed all values .But not able to show pop up at top.i need to show pop up at this image position
But in that project the position is in centre. Knindly any one can help me out.I need show pop up at top Like this image
Thanks in advance !
Your question is not clear.I assume that you want to show pop at top of your viewcontroller instead of that project popup showing at centre.If so, then this is your solution:
I will explain with that github project that you post in your question.
you can change what ever you want in your own project. Go to ENViewController.m.And change the code to
- (IBAction)showPopUp:(id)sender
{
UIViewController *vc = [[UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil] instantiateViewControllerWithIdentifier:#"PopUp"];
vc.view.frame = CGRectMake(20, 30, 270.0f, 230.0f);
[self presentPopUpViewController:vc];
}
You can also change your popup viewcontroller size and update that size,height in this line on your showpopup action method:
vc.view.frame = CGRectMake(20, 30, Any size, Any height);
And if you want to change your postion of pop up view means .you can use any X , Y Values in this line on your showpopup action method:
vc.view.frame = CGRectMake(x, Y, Any size, Any height);
Then go to UIViewController+ENPopUp.m On under //Customize popUpView.delete one line(i have comment that).
// Customize popUpView
popUpView.layer.cornerRadius = 8.0f;
popUpView.layer.masksToBounds = YES;
popUpView.layer.zPosition = 99;
popUpView.tag = kENPopUpViewTag;
//popUpView.center = overlayView.center;
[popUpView setNeedsLayout];
[popUpView setNeedsDisplay];
[overlayView addSubview:popUpView];
[sourceView addSubview:overlayView];
Hope this helpfull.If not please ask your question clear .Let me know !

Why would an activity indicator show up properly on iPhone but not on iPad?

I have my app setup to show this view when it is loading data:
self.loadingView = [UIView new];
self.loadingView.frame = CGRectMake(0, 0, self.tableView.frame.size.width, self.view.frame.size.height);
self.loadingView.backgroundColor = [UIColor groupTableViewBackgroundColor];
[self.view addSubview:self.loadingView];
[self.view bringSubviewToFront:self.loadingView];
self.activityIndicator = [UIActivityIndicatorView new];
self.activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
self.activityIndicator.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
[self.view addSubview:self.activityIndicator];
[self.view bringSubviewToFront:self.activityIndicator];
[self.activityIndicator startAnimating];
Then, I remove it from its superview. It works on iPhone. It works on iPad sometimes too, except for when I'm using the same code in a UISplitViewController. I've tried various adjustments to centering the views, etc., but can't figure it out. What's going wrong?
I've add trouble with activity indicators in the past as well. Make sure you are not calling the startAnimating or stopAnimating while any animations are taking place. I recommend calling the startAnimating selector in viewDidLayoutSubviews.
The line where you set the center of the indicator looks like the source of the problem. self.view.frame.size is probably equal to screen size at this point and so when you show that view controller over the whole screen it's ok, but inside a split view controller it's not because indicator is off-bounds. You can check that from Xcode's Debug -> View Debugging -> Capture View Hierarchy (while the app is running).
Try setting activity indicator's center using autolayout and it should work.

iOS 7 Translucent Modal View Controller

The App Store app on iOS 7 uses a frosted glass-type effect where it is possible to see the view behind. Is this using an API built into iOS 7 or is it custom code. I was hoping it would be the former but I can't see any obvious references in the documentation. Obvious things like (like setting the alpha property on the modal view) don't seem to have any effect.
To see an example, open the App Store app and press the button at the top-right.
With the release of iOS 8.0, there is no need for getting an image and blurring it anymore. As Andrew Plummer pointed out, you can use UIVisualEffectView with UIBlurEffect.
UIViewController * contributeViewController = [[UIViewController alloc] init];
UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
beView.frame = self.view.bounds;
contributeViewController.view.frame = self.view.bounds;
contributeViewController.view.backgroundColor = [UIColor clearColor];
[contributeViewController.view insertSubview:beView atIndex:0];
contributeViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:contributeViewController animated:YES completion:nil];
Solution that works before iOS 8
I would like to extend on rckoenes' answer:
As emphasised, you can create this effect by:
Convert the underlying UIView to an UIImage
Blur the UIImage
Set the UIImage as background of your view.
Sounds like a lot of work, but is actually done pretty straight-forward:
1. Create a category of UIView and add the following method:
-(UIImage *)convertViewToImage
{
UIGraphicsBeginImageContext(self.bounds.size);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
2. Make an image of the current view and blur it by using Apple's Image Effect category (download)
UIImage* imageOfUnderlyingView = [self.view convertViewToImage];
imageOfUnderlyingView = [imageOfUnderlyingView applyBlurWithRadius:20
tintColor:[UIColor colorWithWhite:1.0 alpha:0.2]
saturationDeltaFactor:1.3
maskImage:nil];
3. Set it as background of your overlay.
-(void)viewDidLoad
{
self.view.backgroundColor = [UIColor clearColor];
UIImageView* backView = [[UIImageView alloc] initWithFrame:self.view.frame];
backView.image = imageOfUnderlyingView;
backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
[self.view addSubview:backView];
}
Just reimplemented Sebastian Hojas' solution in Swift:
1. Create a UIView extension and add the following method:
extension UIView {
func convertViewToImage() -> UIImage{
UIGraphicsBeginImageContext(self.bounds.size);
self.drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return image;
}
}
2. Make an image of the current view and blur it by using Apple's Image Effect (I found a reimplementation of this in Swift here: SwiftUIImageEffects
var imageOfUnderlyingView = self.view.convertViewToImage()
imageOfUnderlyingView = imageOfUnderlyingView.applyBlurWithRadius(2, tintColor: UIColor(white: 0.0, alpha: 0.5), saturationDeltaFactor: 1.0, maskImage: nil)!
3. Set it as background of your overlay.
let backView = UIImageView(frame: self.view.frame)
backView.image = imageOfUnderlyingView
backView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.5)
view.addSubview(backView)
I think this is the easiest solution for a modal view controller that overlays everything with a nice blur (iOS8)
UIViewController * contributeViewController = [[UIViewController alloc] init];
UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
beView.frame = self.view.bounds;
contributeViewController.view.frame = self.view.bounds;
contributeViewController.view.backgroundColor = [UIColor clearColor];
[contributeViewController.view insertSubview:beView atIndex:0];
contributeViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:contributeViewController animated:YES completion:nil];
There is no API available in the iOS 7 SDK which will allow you to "frost" the underlaying view controller.
What I have done is render the underlaying view to an image, which I then frosted and set that as background the the view that is being presented.
Apple provides a good example for this: https://developer.apple.com/downloads/index.action?name=WWDC%202013
The project you want is called, iOS_RunningWithASnap
A little simplier way to achieve this (based on Andrew Plummer's answer) with Interface Builder (also it removes side effect that appears in Andrews answer):
In IB add Visual Effect View to your View Controller under your other views;
Make top, bottom, left, right constraints from Visual Effect View to top (parent) View, set all of them to 0;
Set Blur Style;
Add the code where you present your new fancy View Controller:
UIViewController *fancyViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"yourStoryboardIDFOrViewController"];
fancyViewController.view.backgroundColor = [UIColor clearColor];
fancyViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:fancyViewController
animated:YES
completion:nil];
Actually, the second and third lines are VERY important - otherwise controller will blink and then turn black.
Since iOS 8, this works:
let vc = UIViewController()
vc.view = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
vc.modalPresentationStyle = .OverFullScreen
let nc = UINavigationController(rootViewController: vc)
nc.modalPresentationStyle = .OverFullScreen
presentViewController(nc, animated: true, completion: nil)
The key is the .OverFullScreen flag and ensuring the viewControllers have a blur UIVisualEffectView that is the first visible view.
As #rckoenes said, there is no Apple provided framework to get that effect. But some people out there already built good alternatives, like this one for example:
https://github.com/JagCesar/iOS-blur/
A couple of alternative approaches that also work on iOS 5 and 6:
FXBlurView: https://github.com/nicklockwood/FXBlurView
iOS RealtimeBlur: https://github.com/alexdrone/ios-realtimeblur
Fast & easy solution
with XIB support you can use for the old school boys
https://github.com/cezarywojcik/CWPopup
Instead of presenting the viewController as a modalView, you could add it as a child viewController and create a custom animation. You would then only need to change the default view of the viewController to a UIToolBar in viewDidLoad.
This will allow you to mimic the appstore's blurred modal view as closely as possible.
I have uploaded my take of the blurred view controller to [GitHub][1]. It also comes with a segue subclass so you can use it in your storyboards.
Repository: https://github.com/datinc/DATBlurSegue
Apple released the UIImageEffect category for those effects. Those category should be added manually to the project, and it support iOS7.
You can use UIToolbar as background.
By default UIToolbar have 50px height.
Add auto layout constraints on UIToolbar.
Then select height constraint and modify it.
Hierarchy will look like this:
UIView -> clear colour for background.
- UIToolbar
- Other contents.

Custom size for Modal View loaded with Form Sheet presentation

I'm trying to load a UIViewController in iPad with Form Sheet presentation. The problem is the size of this new view, i put the size values in the IBuilder but the modal view take a fixed value.
Also i tried to make this in prepareForSegue like this:
HelpViewController *viewController = segue.destinationViewController;
viewController.view.superview.frame = CGRectMake(0, 0, 200, 200);
But don't work, any help? Thanks!
For iOS 8, use:
self.preferredContentSize = CGSizeMake(width, height);
I've placed this in viewDidLoad.
Swift 3
self.preferredContentSize = CGSize(width: 100, height: 100)
In Attributes inspector check Use Preferred Explicit Size
Setting preferredContentSize didn't work for me on iOS 11 for example when presenting EKEventEditViewController.
It works only if I override getter of preferredContentSize. Something like this:
private class CLEventEditViewController: EKEventEditViewController {
override var preferredContentSize: CGSize {
get {
if let fullSize = self.presentingViewController?.view.bounds.size {
return CGSize(width: fullSize.width * 0.5,
height: fullSize.height * 0.75)
}
return super.preferredContentSize
}
set {
super.preferredContentSize = newValue
}
}
}
EDIT
Use preferredContentSize.
Old
You can try this for show view in center
HelpViewController * viewController = [[[HelpViewController alloc] init] autorelease];
viewController.modalPresentationStyle=UIModalPresentationFormSheet;
viewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:viewController animated:YES completion:^{
viewController.view.superview.frame = CGRectMake(0, 0, 200, 200);
viewController.view.superview.center = self.view.center;
}];
I solved it like #Stuart Campbell and #Viruss mca.
Edited
After #Erich's comment, I rewrote it to run in iOS 8 too. Below is the code:
HelpViewController * viewController = [[[HelpViewController alloc] init]];
viewController.modalPresentationStyle=UIModalPresentationFormSheet;
[self presentViewController:viewController animated:YES completion:nil];
--
//HelpViewController.m
- (void) viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
if (!didLayout) {
[self layout];
didLayout = YES;
}
}
- (void) layout{
self.view.superview.backgroundColor = [UIColor clearColor];
CGRect screen = self.view.superview.bounds;
CGRect frame = CGRectMake(0, 0, <width>, <height>);
float x = (screen.size.width - frame.size.width)*.5f;
float y = (screen.size.height - frame.size.height)*.5f;
frame = CGRectMake(x, y, frame.size.width, frame.size.height);
self.view.frame = frame;
}
My solution is based heavily on other solutions posted here but since I had to try many different things to get it to actually work I am posting it. Mine is for iOS 10 with Swift 3.1 in a portrait-mode only app. (Untested in landscape mode) The goal of my solution was to display a modal that was smaller than the presenting view, and such that I could see the presenting view in the background.
I had to configure the UIViewController properly in Interface Builder or my code wouldn't work. Here are my settings. I found my solution to work with both Cross Dissolve and Cover Vertical transition styles. I think the key for me in IB was the Over Full Screen for Presentation - it didn't appear to work with some other values for this setting.
Here is the code in the UIViewController I want to present modally. Then I just call it using present(_:animated:completion:) elsewhere. Also, in the VC I will present modally, I have a bool, didLayout initialized as false:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if !didLayout {
let width:CGFloat = self.view.bounds.width * 0.95 //modify this constant to change the amount of the screen occupied by the modal
let height:CGFloat = width * 1.618 //golden ratio
self.view.superview!.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.15) //slightly dim the background to focus on the modal
let screen = self.view.superview!.bounds
let frame = CGRect(x: 0, y: 0, width: width, height: height)
let x = (screen.size.width - frame.size.width) * 0.5
let y = (screen.size.height - frame.size.height) * 0.5
let mainFrame = CGRect(x: x, y: y, width: frame.size.width, height: frame.size.height)
self.view.frame = mainFrame
didLayout = true
}
}
I got around this problem by putting my content inside a view in the modal vc. Then setting the vc background transparent and in viewWillAppear settings the formsheet background transparent. This means you only see the content.
// In Modal vc
- (void)viewWillAppear:(BOOL)animated
{
self.view.superview.backgroundColor = [UIColor clearColor];
[super viewWillAppear:animated];
}
I set it all from storyboard and used a segue, if using code you would need to set this also.
parentViewController.modalPresentationStyle = UIModalPresentationPageSheet;
If you are using a view in XIB that is set as a modally presented view for a view controller. A very easy way to fix this is to simply change the Size Metrics to Freeform (See Figure 1.0) and resize the view to whatever you want it to be. The view will appear with these metrics when loaded modaly.
Setting Preferred Content Size didn't help in my case but this fixed my issue. It
Figure 1.0:
I also had this issue, You should resize superview's frame after presenting it.
HelpViewController *viewController = segue.destinationViewController;
viewController.modalPresentationStyle = UIModalPresentationPageSheet;
[self presentViewController:viewController animated:YES completion:nil];
viewController.view.superview.frame = CGRectMake(0, 0, 200, 200);
Erich's post worked for me, but on iOS 10 with Swift 3, I had to use:
self.preferredContentSize = CGSize(width, height)
I too placed it in viewdidload
Also, like avdyushin said, I had to check the Use Preferred Explicit Size box.

How to update iOS PhotoScroller sample code

I'm using altered sample code from PhotoScroller within my app. I have a table view of image thumbnails, and I can pass the array of images that populate that table to PhotoViewController. Currently, PhotoViewController starts with the first image in my array and I can scroll back and forth. This works properly as Apple's sample code.
Now What I want to do is tap a table cell with thumbnail, and start scrolling images beginning with the image in my array at that index. Ex: if I have 5 images in a table and I tap image #3, I want the first image in PhotoViewController to be that third image, and able to scroll left or right to #2 or #4. Hope this makes sense.
I see in PhotoViewController that sub views are being added per image. Any way I can tell it "jump to view #3" without destroying the other views or their overall order of appearance? Any ideas or advice is welcome. Code can be found on the iOS developer site for PhotoScroller sample code.
Ok, I'm rambling... Thanks in advance for your help!
The way I do this is to have a variable called startingPage which gets set in the initialiser of the photo view controller. Then when the pages are being created, first set the correct offset for the scroll view.
So in the PhotoScroller case that would be in loadView. Like so:
- (void)loadView
{
// Step 1: make the outer paging scroll view
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.showsVerticalScrollIndicator = NO;
pagingScrollView.showsHorizontalScrollIndicator = NO;
pagingScrollView.contentSize = [self contentSizeForPagingScrollView];
pagingScrollView.delegate = self;
self.view = pagingScrollView;
// Set the content offset of the scrollview
CGRect bounds = pagingScrollView.bounds;
CGPoint contentOffset = CGPointMake(bounds.size.width * startingPage, 0.0f);
[pagingScrollView setContentOffset:contentOffset animated:NO];
// Step 2: prepare to tile content
recycledPages = [[NSMutableSet alloc] init];
visiblePages = [[NSMutableSet alloc] init];
[self tilePages];
}

Resources