xcode: trying to capture a partial screen - graphics

I must be doing something wrong, but I could use some advice on the following:
I am trying to capture a partial screen on both iPad and iPad retina.
I can get the portrait views ok, but I cannot get the right side of a landscape view to be in bounds.
This is the code I'm using (I did not have this problem before UIGetScreenImage() was made contraband)..
CGRect screenRect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContext(screenRect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor blackColor] set];
CGContextFillRect(ctx, screenRect);
[self.view.layer renderInContext:ctx];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef imageRef = CGImageCreateWithImageInRect([img CGImage], CGRectMake (0, 100, self.view.bounds.size.width, (self.view.bounds.size.height - 200)));
UIImage *img2Save = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
// Request to save the image to camera roll
UIImageWriteToSavedPhotosAlbum(img2Save, self, nil, nil);
These are the two images I get for portrait, and landscape:

If you are using your window as your frame, it will always show up in portrait mode. You can set screenRect to a full-screen view, which should work in both portrait and landscape mode.

Related

How do I change the background color of a tabbed page in Xamarin iOS?

I need to change the background color of the currently tabbed page in my UITabBarController. I've searched through every stackoverflow post I could find but nothing worked for me. I thought there would be something like UITabBar.Appearance.SelectedImageTintColor, just for the background color but it doesn't seem so.
For example, I want to change the color of that part when I am on the right tab:
Does someone know how to do that?
You could invoked the following code in your UITabBarController
public xxxTabBarController()
{
//...set ViewControllers
this.TabBar.BarTintColor = UIColor.Red;
}
Update
//3.0 here is if you have three child page in tab , set it as the current value in your project
//
var size = new CGSize(TabBar.Frame.Width / 3.0, IsFullScreen());
this.TabBar.SelectionIndicatorImage = ImageWithColor(size,UIColor.Green);
double IsFullScreen()
{
double height = 64;
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0)
{
height = 84;
}
}
return height;
}
UIImage ImageWithColor(CGSize size, UIColor color)
{
var rect = new CGRect(0, 0, size.Width, size.Height);
UIGraphics.BeginImageContextWithOptions(size, false, 0);
CGContext context = UIGraphics.GetCurrentContext();
context.SetFillColor(color.CGColor);
context.FillRect(rect);
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image;
}
The trick is to use the SelectionIndicatorImage Property of the UITabBar and generate a completely filled image with your desired color using the following method:
private UIImage ImageWithColor(CGSize size)
{
CGRect rect = new CGRect(0, 0, size.Width, size.Height);
UIGraphics.BeginImageContext(size);
using (CGContext context = UIGraphics.GetCurrentContext())
{
context.SetFillColor(UIColor.Green); //change color if necessary
context.FillRect(rect);
}
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image;
}
To initialize everything we override ViewWillLayoutSubviews() like this:
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
// The tabbar height will always be 49 unless we force it to reevaluate it's size on runtime ...
myTabBar.InvalidateIntrinsicContentSize();
double height = myTabBar.Frame.Height;
CGSize size = new CGSize(new nfloat(myTabBar.Frame.Width / myTabBar.Items.Length, height));
// Now get our all-green image...
UIImage image = ImageWithColor(size);
// And set it as the selection indicator
myTabBar.SelectionIndicatorImage = image;
}
As mentioned in this article (google translating it step by step when necessary lol) calling InvalidateIntrinsicContentSize() will force the UITabBar to reevaluate it's size and will get you the actual runtime height of the tab bar (instead of the constant 49 height value from XCode).

How can I change a color of image and label on UITabBar on iOS 7.1?

How can I change a color of image and label on UITabBar on iOS 7.1? On iOS 7 I could make it by Tint property. But on iOS 7.1 it doesn't work.
It works in the same way in iOS 7 and iOS 7.1!
In AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Add this if you only want to change Selected Image color
// and/or selected image text
[[UITabBar appearance] setTintColor:[UIColor redColor]];
// Add this code to change StateNormal text Color,
[UITabBarItem.appearance setTitleTextAttributes:
#{NSForegroundColorAttributeName : [UIColor greenColor]}
forState:UIControlStateNormal];
// then if StateSelected should be different, you should add this code
[UITabBarItem.appearance setTitleTextAttributes:
#{NSForegroundColorAttributeName : [UIColor purpleColor]}
forState:UIControlStateSelected];
return YES;
}
In every ViewController: (if you want to change the unselected image color)
- (void)viewDidLoad
{
[super viewDidLoad];
// changing the unselected image color, you should change the selected image
// color if you want them to be different
self.tabBarItem.selectedImage = [[UIImage imageNamed:#"yourImage_selectedImage"]
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
self.tabBarItem.image = [[UIImage imageNamed:#"yourImage_image"]
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
The clue of this code is 'UIImageRenderingModeAlwaysOriginal':
Rendering Modes by Apple Documentation:
UIImageRenderingModeAutomatic, // Use the default rendering mode for the context where the image is used
UIImageRenderingModeAlwaysOriginal, // Always draw the original image, without treating it as a template
UIImageRenderingModeAlwaysTemplate, // Always draw the image as a template image, ignoring its color information
UITabBarItem has never had a tint property. No built-in class has ever had a tint property. Nothing has changed here.
In iOS 7 and 7.1, a UITabBar has a tintColor property because it is a UIView.
This changes the tint of both the image and the label, when selected.
- (void)viewDidLoad
{
[super viewDidLoad];
[[UITabBar appearance] setTintColor:[UIColor redColor]];
}

UIScrollView won't scroll on iOS 7 after popping the view controller

My app's home screen has a UIScrollView that contains a UIWebView and a UIButton. The scroll view's content size is set accordingly after loading the web view.
The user can return to the home screen at anytime by simply pressing an icon in a tab bar. This action clears all of the view controllers out of the navigation controller and adds the home screen's controller to the navigation controller. The home screen is redisplayed correctly and the scroll view works just fine.
The problem I'm encountering is when the user presses a "back" button to return the to home screen, which pops the current view controller. The page redisplays fine, but you can't scroll anymore.
I've stepped through the code numerous times and the scroll view's content size is being set to the same value no matter which way you return to the home screen.
It's important to note that the scrollview only stops working under iOS 7. It works as expected under iOS 6.
The web page is loaded in viewWillAppear:
-(void)viewWillAppear:(BOOL)animated
{
NSString *fullURL = #"http://somewhere.com/app-homepage/index.html";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:requestObj];
[self.scrollView setContentOffset:CGPointZero];
}
The scroll view is dynamically resized in webViewDidFinishLoad:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
webView.scrollView.scrollEnabled = NO;
CGRect frame = webView.frame;
frame.size.height = 1;
webView.frame = frame;
CGSize fittingSize = [webView sizeThatFits:CGSizeZero];
frame.size = fittingSize;
self.webViewHeightConstraint.constant = frame.size.height;
self.featuredCelebritiesButtonTopVerticalSpaceConstraint.constant = frame.size.height + 8;
CGSize svContentSize = self.scrollView.contentSize;
svContentSize.height = frame.size.height + 65;
self.scrollView.contentSize = svContentSize;
webView.frame = frame;
[self.activity stopAnimating];
}

UIGraphicsBeginImageContext created image stays in memory forever

I'm creating many colour variations of an image using Core Graphics. I need to create about 320 in total but gradually, the memory usage of the app keeps increasing until it crashes. From Instruments, I see that more CGImage objects are being created and stay alive. I want to release them because I store the images to the cache directory in PNG format.
I have searched through all other solutions I could find without success. Any help is appreciated. Thanks.
Here's the main part:
+(UIImage *)tintedImageFromImage:(UIImage *)sourceImage colour:(UIColor *)color intensity:(float)intensity {
if (UIGraphicsBeginImageContextWithOptions != NULL) {
UIGraphicsBeginImageContextWithOptions(sourceImage.size, NO, 0.0);
} else {
UIGraphicsBeginImageContext(sourceImage.size);
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rect = CGRectMake(0, 0, sourceImage.size.width, sourceImage.size.height);
// draw alpha-mask
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, sourceImage.CGImage);
// draw tint color, preserving alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
[color setFill];
CGContextFillRect(context, rect);
//Set the original greyscale template as the overlay of the new image
sourceImage = [self verticallyFlipImage:sourceImage];
[sourceImage drawInRect:CGRectMake(0,0, sourceImage.size.width,sourceImage.size.height) blendMode:kCGBlendModeMultiply alpha:intensity];
UIImage *colouredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
colouredImage = [self verticallyFlipImage:colouredImage];
return colouredImage;
}
this is used to flip the image:
+(UIImage *)verticallyFlipImage:(UIImage *)originalImage {
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:originalImage];
UIGraphicsBeginImageContext(tempImageView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, tempImageView.frame.size.height);
CGContextConcatCTM(context, flipVertical);
[tempImageView.layer renderInContext:context];
UIImage *flippedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return flippedImage;
}
Add to verticallyFlipImage the line tempImageView.image = nil; in order to make the image view release the image. This solves the problem.

Saving the edited image in camera roll

I'm working on an Acne app in which I have to choose image from UIImagePicker and after adding subViews to it I want to save it in camera roll.
Problem: If I add UIImageView as a subView to the superView, the pickerImage does not save with subView.
And if I add that UIImage as subView to the Picker Image, I am unable to move the added UIImage Views.
I am using the following code for saving images:
-(IBAction)savePhoto
{
NSParameterAssert(imgToDisplayFromPicker.image);
UIImageWriteToSavedPhotosAlbum(imgToDisplayFromPicker.image, nil, nil, nil);
}
Finally Found the Solution :
CGRect contextRect = CGRectMake(6, 6, 302, 230);
UIGraphicsBeginImageContext(contextRect.size);
[self.view.layer renderInContext : UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], contextRect);
UIImage * newImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:viewImage.imageOrientation];
UIImageWriteToSavedPhotosAlbum(newImage, nil, nil, nil);

Resources