UIImageView on top and set size - ios

1) I have a UIView with a UIImageView on it, i load pictures from the image gallery. I want to know how I would "center" the picture on the screen and make that the aspect ratio isn't changed. For instance if I load a picture that is on landscape mode, how do I make sure that the picture isn't stretched all over the screen? My app is working in portrait mode.
2) In that same view I want to add the effect that when the user touches the screen the botton menu fades out and back in when he presses again. I'm not sure what that is called and I couldn't get the tap gesture recognizer to work.
EDIT:
I set the UIImageView on page load
- (void)viewDidLoad
{
[super viewDidLoad];
xlabel = [[UILabel alloc] initWithFrame:self.setLablePosition];
xlabel.backgroundColor = [UIColor clearColor];
imgView.image = self.appDelegate.theImg; // now the image is put on a UIImageView that is "full screen"
xlabel.text = #"Some text";
[imgView addSubview:xlabel];
// Do any additional setup after loading the view.
}
and as for Tap gesture :
-(IBAction)screenTapped{
NSLog(#"screen Tapped");
}
the IBAction is linked to the tap gesture recognizer.

For centering the UIImageView in the view you would do the following
//First give imgView the correct size
//You may need to divide the size by some constant if the image is too big
imgView.frame = CGRectMake(0, 0, self.appDelegate.theImg.size.width, self.appDelegate.theImg.size.width);
//Then center it
imgView.center = self.view.center;
For adding the tap gesture recognizer do the following
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(screenTapped)];
//By deafualt interaction is disabled
imgView.userInteractionEnabled = YES;
[imgView addGestureRecognizer:recognizer];

My solution was
1) add imgView.contentMode = UIViewContentModeScaleAspectFit;
2) like Omar Abdelhafith said i added imgView.userInteractionEnabled = YES;, the UITapGestureRecognizer for me was created it the storyboard.

Related

Rotation gesture changing view frame

What I want to achieve: I want to create a copy of selected view.
I have two UIImageViews on UIView. I am selecting both the views and want to clone both the views.
Everything is working fine until I am not rotating the UIImageView. If am rotating the view UIImageView changing its frame.
UIView *viewClone = [[UIView alloc]initWithFrame:CGRectMake(fltLeadingMin, fltTopMin, fltCloneViewWidth, fltCloneViewHeight)];
viewClone.backgroundColor = [UIColor redColor];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePan:)];
[viewClone addGestureRecognizer:panGesture];
for (UIImageView *imgView in arrSelectedViews) {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:imgView];
UIImageView *imgViewClone = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
imgViewClone.frame = CGRectMake(imgViewClone.frame.origin.x - viewClone.frame.origin.x, imgViewClone.frame.origin.y - viewClone.frame.origin.y, imgView.frame.size.width, imgView.frame.size.height);
imgViewClone.backgroundColor = UIColor.blueColor;
[viewClone addSubview:imgViewClone];
}
Here is a screenshot of how it looks like now:
After rotating the image, its frame won't work anymore and that's the reason for your issue.
You can take a look at Apple document for UIView's transform property
When the value of this property is anything other than the identity transform, the value in the frame property is undefined and should be ignored.
The solution for this situation is using center and transform properties instead of frame.
UIView *viewClone = [[UIView alloc]initWithFrame:CGRectMake(fltLeadingMin, fltTopMin, fltCloneViewWidth, fltCloneViewHeight)];
viewClone.backgroundColor = [UIColor redColor];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePan:)];
[viewClone addGestureRecognizer:panGesture];
for (UIImageView *imgView in arrSelectedViews) {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:imgView];
UIImageView *imgViewClone = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
// This is the frame before you rotate image, can be replace with another size
CGRect originalFrame = CGRectMake(0, 0, 200, 200);
imgViewClone.frame = originalFrame
// Using center and transform instead of current frame
imgViewClone.center = imgView.center;
imgViewClone.transform = imgView.transform;
imgViewClone.backgroundColor = UIColor.blueColor;
[viewClone addSubview:imgViewClone];
}

How to set frame for TapGesture Recognizer

I have an imageview and I want to tap on only one side of imageview. Is it possible to set frame for a gesture? Can anyone help with a solution?
Use UIGestureRecognizerDelegate, i think you can get the idea on how to compare:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch locationInView:yourview].x < somePoint.x) {
return false;
} else {
return true;
}
}
you could overlay a view on top of the imageview and add the tap recognizer to this new view, something like this will make the left hand side of the image tapable
UIView tapView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, imageView.frame.size.width/2, imageView.frame.size.height)];
[imageView addSubView:tapView]
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[tapView addGestureRecognizer:singleFingerTap];
You can simply put UIView on top of your imageView with frame as per your requirement and put tap gesture on that UIView.
You can do this by storyboard / xib or by programmatically.
By programmatically, for example - you want to tap only within the area with width of 50 px of your imageView. For this:
UIView *vw = [[UIView alloc] initWithFrame:CGRectMake(imgView.frame.origin.x, imgView.frame.origin.y, 50, imgView.frame.size.height)];
// add gesture to view
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 2;
[vw addGestureRecognizer:tapGesture];
[imgView addSubview:vw];
now to handle your double tap
-(void)handleTapGesture:(UITapGestureRecognizer *)gesture
{
// handle double tap
}

Adding scrollview to a view

I have tried Adding UIScrollView to a UIViewController, and I can never get my view to move down when I scroll, either on a simulator on a real device. I have also tried increasing the size, so my code is as follows:
+(void)addScrollViewToView:(UIView *)view
{
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, view.bounds.size.width * 2, view.bounds.size.height * 2)];
scrollView.backgroundColor = [UIColor clearColor];
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
scrollView.showsVerticalScrollIndicator = YES;
scrollView.showsHorizontalScrollIndicator = YES;
scrollView.contentSize = CGSizeMake(view.bounds.size.width * 2, view.bounds.size.height * 2);
[view insertSubview:scrollView atIndex:0];
//[view sendSubviewToBack:scrollView]; - commented out
}
It is called within viewDidLoad like so:
#implementation MyLoginViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[Utils addScrollViewToView:self.view];
self.passwordTextField.secureTextEntry = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
} // viewDidLoad method ends here
There is never any response when I try and scroll up with my mouse on a simulator. There is a background image to my view controller that I created using a storyboard. Would changing the index make any difference?
It happen because you add gesture recognizer. Gesture recognizer blocks and not pass your touch.
You can make this for dismiss keyboard with UIScrollView:
+(void)addScrollViewToView:(UIView *)view
{
// your code
scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
}
And remove UITapGestureRecognizer.
Or is it because your frame size is the same as your content size? The scroll view will only scroll if its content is bigger than its frame.
What did the trick was adding the view to the scrollview.
I.e.:
View >
ScrollView >
View that I wanted to scroll
Not:
View that I wanted to scroll >
ScrollView.

How to assign and use array of imageViews using tag

I created arrays of imageViews in UIScrollView programmatically and made then user interacted by assigning them tap gesture. Now, I want to differentiate, which image view is clicked so that I can get images from clicked imageView. However, I was unable to assign them different tag. Here is my code. I am adding 15 images Views.
for (int i = 0; i < 15; i++) {
originx = ((_imageView.frame.size.width+5)*i); //Calculate origin x for each image view.
_imageView = [[UIImageView alloc]initWithFrame:CGRectMake(originx, self.view.frame.origin.y+5, imageViewHeightWidth, imageViewHeightWidth)];
[_imageView setBackgroundColor:[ UIColor colorWithRed:191.0/255.0 green:65.0/255.0 blue:78.0/255.0 alpha:0.5]];
//_imageView.layer.cornerRadius = 10.0;
_imageView.image = [UIImage imageNamed:[_imgArray objectAtIndex:i]];
//Enabling user interaction for gesture.
[_imageView setUserInteractionEnabled:YES];
[_imageView setMultipleTouchEnabled:YES];
//Tap Gesture enabled.
_gesture =[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapTheImage:)];
_gesture.numberOfTapsRequired = 1;
//Add a tap gesture.
[_imageView addGestureRecognizer:_gesture];
//Assigning the tag to image View.
_imageView.tag = 200+i;
//Adding image in to scroll view.
[_gallaryScrollView addSubview:_imageView];
}
//Here i am getting same tag value for every imageView. i.e. "214".
-(void)tapTheImage:(id)sender
{
NSLog(#"The tag value of imagView is%ld",(long)[_imageView tag]);
}
Change TapTheImage method
-(void) TapTheImage:(UITapGestureRecognizer *)gestureRecognizer{
//Get the View
UIImageView *tableGridImage = (UIImageView*)gestureRecognizer.view;
NSLog(#"%d",tableGridImage.tag);
}
You are not creating a new object of UIImageView.
Change the line
_imageView = [[UIImageView alloc]initWithFrame:CGRectMake(originx, self.view.frame.origin.y+5, imageViewHeightWidth, imageViewHeightWidth)];
to
UIImageView *_imageView = [[UIImageView alloc]initWithFrame:CGRectMake(originx, self.view.frame.origin.y+5, imageViewHeightWidth, imageViewHeightWidth)];

UIScrollView with multiple subViews

I have a UIScrollView with many other subviews inside it. Most of the subviews are UITextView's and when they are all loaded, the scrolling and everything is fine. But for one of the views, I am loading a UIView with a MKMapView and a UITextView inside of it. When the user wants to scroll the UIScrollView, they cannot touch the UIView or its contents. I cannot set setUserInteractionEnabled to NO because I need the user to be able to click on the MKMapView and then go to another UIViewController for the map. Are there any suggestions regarding this? I have my code for the above below:
CGRect dealDescRect = CGRectMake(10, 10, delegate.scrollView.frame.size.width - 22 - 20, 120);
mapView = [[MKMapView alloc] initWithFrame:dealDescRect];
mapView.layer.cornerRadius = cornerRadius;
mapView.scrollEnabled = NO;
mapView.zoomEnabled = NO;
BOOL result = [self loadAddressIntoMap];
if (result == TRUE) {
UITapGestureRecognizer* recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
[mapView addGestureRecognizer:recognizer];
}
UITextView *addressTextView = [self generateTextView:addressText :5];
addressTextView.editable = NO;
[addressTextView setFont:[UIFont systemFontOfSize:fontSize]];
[addressTextView setUserInteractionEnabled:NO];
CGRect addressTextViewFrame = addressTextView.frame;
addressTextViewFrame.origin.x = 0;
addressTextViewFrame.origin.y = 130;
addressTextViewFrame.size.height = addressTextView.contentSize.height + 15;
addressTextView.frame = addressTextViewFrame;
CGRect viewRect = CGRectMake(10, 145, delegate.scrollView.frame.size.width - 22, addressTextView.contentSize.height + 135);
viewRect.origin.x = 11;
viewRect.origin.y = startTop;
UIView *view = [[UIView alloc] initWithFrame:viewRect];
view.layer.cornerRadius = cornerRadius;
[view setBackgroundColor:[UIColor whiteColor]];
[view addSubview:mapView];
[view addSubview:addressTextView];
EDIT
For some weird reason, if I change the UIView to a UITextView, it works! Not sure what the real solution here is though. I just disable editing.
If it were me, instead of using gesture recognizers to watch for a tap on the map I'd create a UIButton of a custom type (UIButtonTypeCustom) and give it no background and no text, and place it on top of the map with the same frame as the map.
This has the benefit of preventing the user from interacting with the map, moving to the next page as you want and if the user starts scrolling even when over the map they are able to.

Resources