I would like to take a screenshot of ViewController, blur the image, send it to ProfileViewController, then set it as the background of ProfileViewController. This should not be that difficult as each task is pretty straightforward, I am just having difficulty finding the correct syntax as to how to do this.
The way I want this to work is such:
The user starts on ViewController, the main view.
Upon the click of a button (labeled profTap) the user is taken to ProfileViewController.
ProfileViewController is displayed through a segue (present modally) with its background set as a blurred image of the previous view from ViewController.
If someone could show me with code how to send the image to ProfileViewController I would be most appreciative. For reference, here is my code below that I have for now of the ViewController. I believe I am capturing the image correctly, I am jsut not sure what to do from here to send it to the ProfileViewController.
#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
#import "ProfileViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)profTap:(id)sender {
UIGraphicsBeginImageContext(self.mainView.bounds.size);
[self.mainView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *mainViewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *data = UIImagePNGRepresentation(mainViewImage);
// NEXT: blur image, and send to ProfileViewControoler
// UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"mainViewImage"]];
// [self.view addSubview:backgroundView];
}
- (IBAction)unwindToHome:(UIStoryboardSegue *)segue {
}
#end
Try something like that
#interface ViewController ()
#property(nonatomic, strong) UIImage *backgroundImage;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)profTap:(id)sender {
}
- (IBAction)unwindToHome:(UIStoryboardSegue *)segue {
self.backgroundImage = [self takeSnapShot];
[self performSegueWithIdentifier:#"nameofyoursegue" sender:nil];
}
//function to take a screenshot of your current controller
- (UIImage *)takeSnapShot {
// Create the image context
CGRect bounds = self.mainView.bounds;
UIGraphicsBeginImageContextWithOptions(bounds.size, NO,
self.view.window.screen.scale);
[self.navigationController.view drawViewHierarchyInRect:bounds
afterScreenUpdates:NO];
// Get the snapshot
UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
// Be nice and clean your mess up
UIGraphicsEndImageContext();
return snapshotImage;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"nameofyoursegue"]) {
ProfileViewController *profileViewController =
[segue destinationViewController];
[profileViewController setBackgroundImage:self.backgroundImage];
}
}
#end
PhotoViewController
#interface ProfileViewController ()
#property(nonatomic, weak) IBOutlet UIImageView *backgroundImageView;
#property(nonatomic, strong) UIImage *backgroundImage;
#end
#implementation ProfileViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.backgroundImageView
setImage:self.backgroundImage];
}
#end
About the blur effect, I advice you to use FXBlurView in your ProfileViewController :
https://github.com/nicklockwood/FXBlurView
Related
Having trouble carrying out a build I am trying to complete.
I have the build 1 and build 2 complete.
Build 1 - A simple blank screen with two text boxes with alignment constraints
Build 2 - When application is run it calls the native back camera of an IOS device.
My third build is these two previous builds together as one, where the native camera shows a live video feed and over layed is the two text boxes with their alignment constraints.
I am unsure how to bring the two bits of code together.
The code i currently have:
Build 1 - .h File
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIView *TestTextBox;
#property (weak, nonatomic) IBOutlet UITextView *TestTetBox2;
#end
Build 1 - .m file
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize TestTextBox;
#synthesize TestTetBox2;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Build 2 - .h file
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIImagePickerControllerDelegate,UINavigationControllerDelegate>
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
#end
Build 2 - .m file
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
if (self.imageView.image == nil) {
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera; //Defualts to Native Camera View
imagePickerController.showsCameraControls = NO; //removes camera controlls
[self presentViewController:imagePickerController animated:NO completion:nil];
}
else{
}
}
-(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
self.imageView.image = image;
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
You cannot present the camera in a custom UIView using the UIImagePickerController. You need to use AVFoundation framework to present a camera in a custom UIView.
I want to cancel the second view controller with a UIBarButtonItem, but I just don't get the code right. Please help.
Viewcontroller.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface ViewController : UIViewController <SecondViewControllerDelegate>
#end
Viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController isKindOfClass:[SecondViewController class]]) {
SecondViewController *vc2 = segue.destinationViewController;
vc2.delegate = self;
}
}
-(void)dismissViewController
{
NSLog(#"dismissed");
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
Secondviewcontroller.h
#import <UIKit/UIKit.h>
#protocol SecondViewControllerDelegate <NSObject>
- (void) dismissViewController;
#end
#interface SecondViewController : UIViewController
#property (weak, nonatomic) id <SecondViewControllerDelegate> delegate;
- (IBAction)backBarButtonItemPressed:(UIBarButtonItem *)sender;
#end
BackbarButton means cancelbutton
Secondviewcontroller.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)backBarButtonItemPressed:(UIBarButtonItem *)sender {
[self.delegate dismissViewController];
}
#end
You can dismiss in secondViewController,I do not see the meaning of Delegate in your code
- (IBAction)backBarButtonItemPressed:(UIBarButtonItem *)sender {
[self dismissViewControllerAnimated:true completion:nil];
}
If you use show segue,and you have a navigationController with these two ViewControllers,Use
- (IBAction)dismiss:(id)sender {
[self.navigationController popViewControllerAnimated:true];
}
I'll post my code first and then I'll explain the problem
RootViewController.h its called SpViewController.h
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "secondViewController.h"
#interface spViewController : UIViewController
<UIImagePickerControllerDelegate,
UINavigationControllerDelegate>
#property BOOL newMedia;
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
#property (strong, nonatomic) spViewController *secondViewController;
#property (strong, nonatomic) UIImageView *image;
#property (strong, nonatomic) UIImage *myImage;
- (IBAction)useCamera:(id)sender;
- (IBAction)useCameraRoll:(id)sender;
#end
spViewController.m
#import "spViewController.h"
#import "secondViewController.h"
#interface spViewController ()
#end
#implementation spViewController
- (IBAction)backtohome:(UIStoryboardSegue *)unwindSegue
{
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)useCamera:(id)sender {
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType =
UIImagePickerControllerSourceTypeCamera;
imagePicker.mediaTypes = #[(NSString *) kUTTypeImage];
imagePicker.allowsEditing = NO;
[self presentViewController:imagePicker
animated:YES completion:nil];
_newMedia = YES;
}
}
- (IBAction)useCameraRoll:(id)sender {
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType =
UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = #[(NSString *) kUTTypeImage];
imagePicker.allowsEditing = NO;
[self presentViewController:imagePicker
animated:YES completion:nil];
_newMedia = NO;
}
}
//image picker delegate
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *chosenImage = info[UIImagePickerControllerEditedImage]; self.myImage = chosenImage;
NSString *mediaType = info[UIImagePickerControllerMediaType];
[self performSelector:#selector(myMethod:) withObject:info afterDelay:0.1];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
UIImage *image = info[UIImagePickerControllerOriginalImage];
_imageView.image = image;
if (_newMedia)
UIImageWriteToSavedPhotosAlbum(image,
self,
#selector(image:finishedSavingWithError:contextInfo:),
nil);
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{
}
}
-(void)myMethod:(NSDictionary *)info {
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"Perform segue");
[self performSegueWithIdentifier:#"Picture Unwind Segue" sender:self];
}];
}
-(void)image:(UIImage *)image
finishedSavingWithError:(NSError *)error
contextInfo:(void *)contextInfo
{
if (error) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle: #"Save failed"
message: #"Failed to save image"
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
//cancel delegate
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier]isEqualToString:#"Picture Unwind Segue"]) {
secondViewController *destinationViewController = [segue destinationViewController];
destinationViewController.imageView.image = self.myImage;
}
}
#end
secondViewController.h
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "spViewController.h"
#interface secondViewController : UIViewController
<UIImagePickerControllerDelegate,
UINavigationControllerDelegate>
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
#property (strong, nonatomic) UIImage *myImage;
#property (strong, nonatomic) UIImageView *image;
#end
secondViewController.m
#import "secondViewController.h"
#import "spViewController.h"
#interface secondViewController ()
#end
#implementation secondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
self.imageView.image = self.myImage;
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
So the problem I'm having is, I can't get the image that has just been selected in the UIImagePickerController to be displayed in the UIImageView, my ImagePickerController was initiated by a button in my previous view controller "spViewController" (rootViewController) I am using Storyboards, I thought if I put in the UIImageView then connected it using an outlet reference it would display there, this doesn't seem to be the case though. If I put the UIImageView in the first view controller and do the same it will display the image but thats not where I want it to go.
Thank you for any help
To fix my problem i decided to save the image and call on it later heres the code i put into my secondViewController.m
{NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filepathJPG = [docsPath stringByAppendingPathComponent:#"imagefile.jpg"];
UIImage *img = [UIImage imageWithContentsOfFile: filepathJPG];
if (img != nil) {
// assign the image to the imageview,
_imageView.image = img;
// Optionally adjust the size
BOOL adjustToSmallSize = YES;
CGRect smallSize = (CGRect){0,0,100,100};
if (adjustToSmallSize) {
_imageView.bounds = smallSize;
}
}
I hope this can help others that have the same problem.
So according to your code , you are setting the property of myImage which is an instance of UIImage from the RootViewController.
so your just passing the data of the image , But your not setting your imageView.image property to the passed image value.
So a possible fix would be to set
imageView.image = myImage in viewDidLoad
or
you can directly access the imageView property from the perform prepare for segue method in the RootViewController and set its image property.
I hope this helps .
Cheers
You can declare a property in AppDelegate class and access it across all controllers using appdelegate shared instance
I am trying to pass data between two view controllers. viewcontroller2 is a delegate of viewcontroller.. note.. i called the delegate property "homie" yes I know this is bad practice but I am just messing around trying to understand the concept.
here is viewcontroller:
#import <UIKit/UIKit.h>
#protocol ViewControllerDelegate <NSObject>
#required
- (void)sendData:(NSString *)theString;
#end
#interface ViewController : UIViewController
#property (nonatomic, assign) id <ViewControllerDelegate> homie;
- (void)doSomething;
- (IBAction)doneText:(id)sender;
#end
implementation:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)doSomething{
}
- (IBAction)doneText:(id)sender {
UITextField *thisField = sender;
if([_homie respondsToSelector:#selector(sendData:)]){
[_homie sendData:[thisField text]];
}
}
now here is the other view controller implementing the first
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface ViewController2 : UIViewController <ViewControllerDelegate>
- (IBAction)hittingbtn:(id)sender;
#property (weak, nonatomic) IBOutlet UITextField *textfield;
#property (strong, nonatomic) ViewController *vc;
#end
implementation:
#import "ViewController2.h"
#interface ViewController2 ()
#end
#implementation ViewController2
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
ViewController *theview = [[ViewController alloc]init];
theview.homie = self;
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// DELEGATE METHOD
- (void)sendData:(NSString *)theString{
[_textfield setText:theString];
}
- (IBAction)hittingbtn:(id)sender {
}
#end
in viewdidload I instantiate the first viewcontroller, and set myself as its delegate. im assuming then when that viewcontroller2 runs the code in its method then it will see if its delegate has implemented the delegate method and use that code.. what am i missing here?
Your problem is that you use ViewControllers wrong. You have initialized ViewController
ViewController *theview = [[ViewController alloc]init];
theview.homie = self;
And what next? You haven't assign it to your properties or something. What have you do? It's simple. You have to implement - (void)prepareForSegue:sender:. First of all in your storyboard set segue's identifier. Then do following.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MySegue"]) {
ViewController *destinationViewController = (ViewController *)[segue destinationViewController];
ViewController.homie = self;
}
}
You need to set the delegate in prepareForSegue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController respondsToSelector:#selector(setHomie)]) {
[segue.destinationViewController setHomie:self];
//or
if ([[segue.destinationViewController isKindOfClass:[ViewController class]]) {
ViewController *destinationViewController = (ViewController *)[segue destinationViewController];
ViewController.homie = self;
}
//or the segue identifier which has already been mentioned
}
The question is, I have 9 buttons on viewcontroller (ViewController), and i have an outlet collection for storing all these buttons outlet.
Then i have an action method for handling click event of these buttons.
What I want is send the button image background (as an UIImage * img)of the CLICKED button, segue to another viewcontroller (vc2),
here are my code :
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardBtns;
- (IBAction)cardAction:(id)sender;
#end
#import "ViewController.h"
#import "ResultViewController.h"
#interface ViewController ()
#property(strong,nonatomic)UIImage *image;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)cardAction:(id)sender {
for(UIButton *cardButton in self.cardBtns){
self.image = [cardButton currentBackgroundImage];
}
[self performSegueWithIdentifier:#"cardSegue" sender:self.image];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
//UIImage * img = [UIImage imageNamed:#"f1"];
UIImage * img = (UIImage *)sender;
ResultViewController *viewcontroller = [segue destinationViewController];
viewcontroller.img = img;
}
#end
in vc2, i have another button here, and i wish to paint this button background img with the img just sent from vc1 segue.
#interface ResultViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIButton *cardBtn;
#property(strong,nonatomic)UIImage *img;
- (IBAction)cardDismiss:(id)sender;
#end
#import "ResultViewController.h"
#interface ResultViewController ()
#end
#implementation ResultViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.cardBtn setImage:self.img forState:UIControlStateNormal];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)cardDismiss:(id)sender {
[self dismissViewControllerAnimated:NO completion:nil];
}
#end
assume my buttons is 1,2,3,4,5,6,7,8,9
for now, whatever buttons i clicked in vc1, it s always displaying as '6' in vc2...
any suggestions? thanks
The problem is this:
- (IBAction)cardAction:(id)sender {
for(UIButton *cardButton in self.cardBtns){
self.image = [cardButton currentBackgroundImage];
}
[self performSegueWithIdentifier:#"cardSegue" sender:self.image];
}
This will set self.image to the last item in self.cardBtns. You want to set self.image to sender.currentBackgroundImage (and change id in the argument type to UIButton *), and just eliminate the loop.