I have a custom UIView XIB that gets loaded onto my ViewController and the frame is adjusted to be collapsed before added to subview. The UIButton tied to my XIB is showing when the frame is smaller than the button location. How can I hide and show my UIButton as the frame is expanding/collapsing? My XIB is not using AutoLayout.
ViewController.m
self.greenView = [[[NSBundle mainBundle] loadNibNamed:#"Green" owner:self options:nil] objectAtIndex:0];
[self.navigationController.view addSubview:self.greenView];
GreenView.h
#interface GreenView : UIView
#property (weak, nonatomic) IBOutlet UIView *expandView;
#property (nonatomic, getter = isExpanded) BOOL expand;
#property (weak, nonatomic) IBOutlet UIButton *testButton;
- (IBAction)testButtonTapped:(id)sender;
#end
GreenView.m
#interface GreenView()
#property (nonatomic) UITapGestureRecognizer *tapGesture;
#end
#implementation GreenView
- (void)awakeFromNib {
CGRect frame = self.frame;
frame.size.height = self.expandView.frame.size.height;
frame.origin.y = 200;
self.frame = frame;
self.expand = NO;
[self.expandView addGestureRecognizer:self.tapGesture];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (UITapGestureRecognizer *)tapGesture {
if (!_tapGesture) {
_tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapClicked:)];
}
return _tapGesture;
}
- (void)tapClicked:(UIGestureRecognizer *)recognizer {
CGRect frame = self.frame;
self.expand = !self.expand;
frame.size.height = self.expand ? gvExpandedHeight : gvCollapsedHeight;
[UIView animateWithDuration:0.5 animations:^{
self.frame = frame;
} completion:^(BOOL finished) {
NSLog(#"Frame after animation: %#", NSStringFromCGRect(self.frame));
}];
}
- (IBAction)testButtonTapped:(id)sender {
NSLog(#"Test button tapped");
}
#end
Collapsed:
Expanded:
GreenView.xib:
GrenenView.xib Struts and Springs:
If I understood you just want to clip it, if the button is outside to the view bounds. In -awakeFromNib add:
self.clipsToBounds = YES;
Using this property you are telling the view to cut everything that is not inside its bounds, views caw draw subviews even if they are place outside. Is a little expensive by means of performance, if you use it a lot or during heavy animations.
One way around could be hide it while the view is collapsed.
You change the frame to frame.origin.y = 200;
I think you have to set the UIButton constraint relative to your GreenView in you nib file
Related
I am trying to make practice app where i can scroll images with page control. I am able to scroll images and able to include the page control. But the problem i face is i am not able to interlink the two. Meaning to say when I scroll the images, the page control is not affected and when i change the page control, the scrolling of the images is unaffected.
I have referred to this: http://www.iosdevnotes.com/2011/03/uiscrollview-paging/ for the scrolling with page control.
Viewcontroller.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIScrollViewDelegate>{
UIScrollView *scrollView;
UIPageControl *pageControl;
BOOL pageControlBeingUsed;
}
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
- (IBAction)changePage;
#end
Viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize scrollView,pageControl;
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if (!pageControlBeingUsed) {
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *images = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"1.jpeg"],[UIImage imageNamed:#"2.jpeg"],[UIImage imageNamed:#"3.jpeg" ], nil];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * images.count, self.scrollView.frame.size.height);
for (int i = 0; i < images.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
UIImageView* imgView = [[UIImageView alloc] init];
imgView.image = [images objectAtIndex:i];
imgView.frame = frame;
[scrollView addSubview:imgView];
}
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = images.count;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.scrollView = nil;
self.pageControl = nil;
}
- (IBAction)changePage{
// update the scroll view to the appropriate page
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
#end
Need some guidance on this... Thanks..
I learned page control and scrollView from this tutorial, its very clearly written, hope it helps you http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
Check whether you have set the delegate of the scroll view to the ViewController
And you have just set the pageControlBeingUsed to YES or NO and you have not used it anywhere in the ViewController
I am a newbie to iphone development and i am doing a simple app for practice. In that app,there is only one view that has an image on it. I want to be able to swipe left or right and have the first image go out of the view and the second image to come in. The images are different and I want it to look like they are connected. I need it to be able to change the image or restart after a series of swipes. I am doing this using ScrollView only.
I have tried something:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIScrollViewDelegate>
{
UIImageView *imgView;
UIScrollView *scrollView;
}
#property (nonatomic,retain)IBOutlet UIImageView *imgView;
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
//- (id)initWithPageNumber:(int)page;
- (IBAction)changePage:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize imgView,scrollView;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
- (id)initWithPageNumber:(int)page{
if (self = [super initWithNibName:#"MyView" bundle:nil])
{
pageNumber = page;
}
return self;
}
*/
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollview
{
scrollView.contentOffset = CGPointMake(scrollview.bounds.size.width, 0);
}
- (IBAction)changePage:(id)sender
{
NSArray *images = [[NSArray alloc] initWithObjects:#"1.jpeg",#"2.jpeg",#"3.jpeg", nil];
scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:scrollView];
CGRect cRect = scrollView.bounds;
for (int i = 0; i < images.count; i++){
imgView = [images objectAtIndex:i];
imgView.frame = cRect;
[scrollView addSubview:imgView];
cRect.origin.x += cRect.size.width;
}
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * images.count, scrollView.bounds.size.height);
scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
}
#end
When i run the app, I am still not able to swipe across the images. Am i doing something wrong? Need some guidance on this. Thanks..
This error indicates that you have a connection in Interface Builder with an IBOutlet that does not exist in your view controller class.
Make sure your IBOutlets are named correctly and that you have removed all obsolete connections in IB.
scrollView.ContentSize = (scrollView.frame.size.width * images.count
,scrollView.frame.size.height)
do this after lopping it will swipe
I have a UIScrollView in which I am adding a subview which is a TimeLineView(a UIView).For the purpose of displaying; initially I just did the same and the TimeLineView got displayed without any problem. But now I want to have a UIView just above the UIScrollView where I can display some information about the the timeline.
Do I need to decrease the height of the UIScrollView so that the UIView gets fit on the space above it? If yes, How would I do that?
If there's another way...then please let me know.
All my initial implementations are as follows :
in .h
#property (nonatomic, readonly) UIScrollView *scrollView;
#property (nonatomic, readonly) TimeLineView *timelineView;
in .m
#synthesize scrollView = scrollView;
#synthesize timelineView = timelineView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self prepareCustomView];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder
{
self = [super initWithCoder:decoder];
if (self) {
[self prepareCustomView];
}
return self;
}
- (void)prepareCustomView {
// Initialization code
// Add main scroll view
[self addSubview:self.scrollView];
// Add timeline view inside scrollview
[self.scrollView addSubview:self.timelineView];
}
- (UIScrollView *)scrollView
{
if (!scrollView) {
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0f, TOP_BAR_HEIGHT, self.bounds.size.width, self.bounds.size.height-TOP_BAR_HEIGHT-FOOTER_HEIGHT)];
scrollView.contentSize = CGSizeMake(self.bounds.size.width,TIMELINE_HEIGHT);
scrollView.scrollEnabled = TRUE;
scrollView.backgroundColor =[UIColor whiteColor];
scrollView.alwaysBounceVertical = TRUE;
}
return scrollView;
}
Thanks in advance for the help.
Yes you have to change y-axis and decrease the height of scrollview by the height of your UIView.You have to change the frame of your scrollview as follows if the scrollview is just below UIView:
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0f, UIViewFrame.size.height+UIViewFrame.origin.y, self.bounds.size.width, self.bounds.size.height-TOP_BAR_HEIGHT-FOOTER_HEIGHT-UIViewFrame.size.height)];
where UIViewFrame is the frame of your UIView.
After seeing some examples, I'm trying to create a window where an Image view could be moved with the PanGestureRecognizer. I don't understand what is missing.
I created and initialized an UIView object
I also created an UIGestureRecognizer for panning, for both views.
I created the method to be selected when Gesture is recognized.
If you have an idea of what is missing, I would be thankful to read it;
Here is my code:
View Controller.h
#import <UIKit/UIKit.h>
#import "bouton.h"
#interface ATSViewController : UIViewController {
boutonHome *bouton; }
#property (retain, nonatomic) boutonHome *bouton;
-(IBAction)handlePanGesture:(UIPanGestureRecognizer*)sender;
#end
View Controller.m
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *image = [UIImage imageNamed:#"back.png"];
CGRect frame = CGRectMake(0, 0, image.size.width, image.size.height);
// Set self's frame to encompass the image
bouton.frame = frame;
bouton.boutonImage = image;
[self.view addSubview:bouton];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
[bouton setUserInteractionEnabled:YES];
[bouton addGestureRecognizer:panGesture];
[self.view setUserInteractionEnabled:YES];
[self.view addGestureRecognizer:panGesture];
// Do any additional setup after loading the view, typically from a nib.
}
-(IBAction)handlePanGesture:(UIPanGestureRecognizer *)sender
{
CGPoint translate = [sender translationInView:self.view];
CGRect newFrame = bouton.frame;
newFrame.origin.x += translate.x;
newFrame.origin.y += translate.y;
sender.view.frame = newFrame;
if(sender.state == UIGestureRecognizerStateEnded)
bouton.frame = newFrame;
}
BoutonHome.h
#import <Foundation/Foundation.h>
#interface boutonHome : UIView
{
UIImage *boutonImage;
}
#property (nonatomic, retain) UIImage *boutonImage;
// Initializer for this object
#end
boutonHome.m
#import "bouton.h"
#implementation boutonHome
#synthesize boutonImage;
#end
So apparently I'm adding the same label over and over. I have an IBOutlet for UILabel that I hooked up in IB. I did that because that's the position I want it in for my UIScrollView. I also want a new label on each page in my ScrollView but I can't figure out how to do it.
Any suggestions for how to accomplish this? Because I'm lost :-/
AnotherMadeUpViewController.h
#import <UIKit/UIKit.h>
#interface AnotherMadeUpViewController : UIViewController<UIScrollViewDelegate>
{
IBOutlet UIPageControl *pageControl;
IBOutlet UIScrollView *scroller;
IBOutlet UILabel *label;
}
#property (nonatomic,retain)IBOutlet UIPageControl *pageControl;
#property (nonatomic,retain)IBOutlet UIScrollView *scroller;
#property (nonatomic,retain)IBOutlet UILabel *label;
-(IBAction)clickPageControl:(id)sender;
#end
AnotherMadeUpViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
scroller.delegate=self;
scroller.pagingEnabled=YES;
scroller.directionalLockEnabled=YES;
scroller.showsHorizontalScrollIndicator=NO;
scroller.showsVerticalScrollIndicator=NO;
scroller.contentSize=CGSizeMake(pageControl.numberOfPages*scroller.frame.size.width, scroller.frame.size.height);
CGFloat labelOriginX = label.frame.origin.x;
CGFloat labelOriginY = label.frame.origin.y;
CGFloat scrollWidth = 0;
int pageNumber = 0;
for (int i=0; i<3; i++)
{
CGRect rect = label.frame;
rect.size.height = label.frame.size.height;
rect.size.width = label.frame.size.width;
rect.origin.x = labelOriginX + scrollWidth;
rect.origin.y = labelOriginY;
label.frame = rect;
label.text = [NSString stringWithFormat:#"%d", pageNumber];
label.textColor = [UIColor redColor];
[scroller addSubview:label];
pageNumber++;
scrollWidth += scroller.frame.size.width;
}
pageControl.numberOfPages=3;
pageControl.currentPage=0;
[self.view addSubview:scroller];
}
You are re-adding the same UILabel instance over and over then, nothing happens other than changing the label's location (frame) in the scrollView's contentView. You'd have to add 8 copies of that label to the scrollView, each in a different frame. If you want to tile an image in the scrollView's background, try setting its backgroundColor to a pattern image created with +[UIColor colorWithPatternImage: ]