You can scroll an UIPickerView both by swiping and by tapping items under or above the selection belt.
You can populate an UIPickerView by either specifying NSString as titles or reusable UIViews for each row.
What I've noticed is that when I switched from providing strings to providing view, tap to scroll no longer worked. Is this expected behavior. Should my views forward some touch events to the UIPickerView?
Thanks
EDIT:
Here's a code sample from my implementation:
// Creating the picker
screenPicker_ = [UIPickerView new];
screenPicker_.showsSelectionIndicator = YES;
screenPicker_.delegate = delegate_;
screenPicker_.dataSource = delegate_;
[self addSubview:screenPicker_];
[screenPicker_ release];
// Row view creation delegate
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
PickerRowView *pickerRowView = (PickerRowView*)view;
if(view == nil)
{
pickerRowView = [[PickerRowView alloc] initWithFrame:CGRectMake(0, 0, pickerView.frame.size.width, PICKER_ROW_HEIGHT)];
}
[pickerRowView SetTitle:#"some title"];
return pickerRowView;
}
// initailizer of the PickerRowView class (an UIView subclass)
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
CGFloat titleHeight = frame.size.height * CONTENT_TO_FRAME_RATIO;
title_ = [[UILabel alloc] initWithFrame:CGRectMake(TITLE_X, (frame.size.height - titleHeight) / 2, frame.size.width, titleHeight)];
[title_ setFont:[UIFont fontWithName:#"StainlessExt-Light" size:titleHeight]];
title_.backgroundColor = [UIColor clearColor];
[self addSubview:title_];
[title_ release];
self.userInteractionEnabled = NO;
}
return self;
}
Setting userInteractionEnabled property to NO for your row views must solve your problem.
In your PickerRowView class, define the following method:
- (void)didMoveToSuperview {
if ([[self superview] respondsToSelector:#selector(setShowSelection:)])
{
[[self superview] performSelector:#selector(setShowSelection:) withObject:NO];
} }
and that should get rid of the highlight
Related
I would like to customize the delete button which is shown when performing the 'swipe to left'-action on a tableview cell. I currently set up a subclass of a UITableViewCell but also want to customize the delete-button which is being shown.
My goal is to place three buttons when swiping.
I choose for another implementation where I was using a UIScrollview in each cell.
http://www.teehanlax.com/blog/reproducing-the-ios-7-mail-apps-interface/
Accepted answer will not work on iOS 7, as there is now UITableViewCellContentView in between. So subviews loop now should look like this(if you want to support older iOS versions too, use currently accepted answer for iOS 6.1-)
for (UIView *subview in self.subviews) {
for (UIView *subview2 in subview.subviews) {
if ([NSStringFromClass([subview2 class]) rangeOfString:#"Delete"].location != NSNotFound) {
// Do whatever you want here
}
}
}
This might help you.
- (void)willTransitionToState:(UITableViewCellStateMask)state
{
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask)
{
for (UIView *subview in self.subviews)
{
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"])
{
UIImageView *deleteBtn = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 64, 33)];
[deleteBtn setImage:[UIImage imageNamed:#"arrow_left_s11.png"]];
[[subview.subviews objectAtIndex:0] addSubview:deleteBtn];
}
}
}
}
Referenced from:
Customize the delete button in UITableView
create custom delete button for uitableview
Custom Delete button On Editing in UITableView Cell
-(void)willTransitionToState:(UITableViewCellStateMask)state{
NSLog(#"EventTableCell willTransitionToState");
[super willTransitionToState:state];
if((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask)
{
UIImageView *deleteBtn = [[UIImageView alloc]initWithFrame:CGRectMake( 320,0, 228, 66)];
[deleteBtn setImage:[UIImage imageNamed:#"BtnDeleteRow.png"]];
[[self.subviews objectAtIndex:0] addSubview:deleteBtn];
[self recurseAndReplaceSubViewIfDeleteConfirmationControl:self.subviews];
[self performSelector:#selector(recurseAndReplaceSubViewIfDeleteConfirmationControl:) withObject:self.subviews afterDelay:0];
}
}
The solutions above didn't work for me for iOS 7, at - (void)willTransitionToState:, the delete button wasn't in the view heirarchy so I wasn't able to manipulate anything. I ended up doing everything on - (void)didTransitionToState:. The example below was specifically for when my cells had some spacing at the top so I'm altering the frame of the delete button. If you want to customize the delete button, you can just add a view on top of the delete button or replace it with your own UIButton
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//your own stuff
//for some reason, editingAccessoryView cannot be nil and must have a non-CGRectZero frame
self.editingAccessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
}
return self;
}
- (void)didTransitionToState:(UITableViewCellStateMask)state
{
[super didTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask)
{
UIView *deleteButton = [self deleteButtonSubview:self];
if (deleteButton) {
CGRect frame = deleteButton.frame;
frame.origin.y += defined_padding;
frame.size.height -= defined_padding;
deleteButton.frame = frame;
}
}
}
- (UIView *)deleteButtonSubview:(UIView *)view
{
if ([NSStringFromClass([view class]) rangeOfString:#"Delete"].location != NSNotFound) {
return view;
}
for (UIView *subview in view.subviews) {
UIView *deleteButton = [self deleteButtonSubview:subview];
if (deleteButton) {
return deleteButton;
}
}
return nil;
}
I have an array that contains 20 images add that images to imageview using scrollview. all image scroll.
I want to add the Carousel circle effect for all my 20 images how may i do thsi i have tried this but not work.
Adding iCarousel.h,iCarousel.m into my bundle defining delegate also.
<iCarouselDataSource,iCarouselDelegate,UIScrollViewDelegate>
-(void)viewDidLoad
{
iCarousel *icrusal = [[iCarousel alloc]initWithFrame:CGRectMake(0,0, 320, 480)];
icrusal.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
icrusal.delegate = self;
icrusal.dataSource = self;
icrusal.type=iCarouselTypeRotary;
icrusal.type=iCarouselTypeCoverFlow;
[self.view addSubview:icrusal];
}
-(NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return 20;
}
-(UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index
{
//ImgView=[[UIImageView alloc]init];
ImgView=[[UIImageView alloc]init];
return ImgView;
}
- (BOOL)carousel:(iCarousel *)carousel shouldSelectItemAtIndex:(NSInteger)index{
return YES;
}
- (CGFloat)carouselItemWidth:(iCarousel *)carousel
{
//usually this should be slightly wider than the item views
return 180;
}
how may i do this thanks in advance.
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{
//create new view if no view is available for recycling
if (view == nil)
{
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 50.0f, 50.0f)];
((UIImageView *)view).image = [UIImage imageNamed:#"apple-logo-1.png"];
view.contentMode = UIViewContentModeCenter;
}
else
{
//get a reference to the label in the recycled view
((UIImageView *)view).image = [UIImage imageNamed:#"apple-logo-1.png"];
}
return view;
}
And you can also add below method to give space between images in iCarousel
- (CGFloat)carousel:(iCarousel *)_carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
{
//customize carousel display
switch (option)
{
case iCarouselOptionWrap:
{
//normally you would hard-code this to YES or NO
return NO;
}
case iCarouselOptionSpacing:
{
//add a bit of spacing between the item views
return value * 1.95f;
}
case iCarouselOptionFadeMax:
{
if (_carousel.type == iCarouselTypeCustom)
{
//set opacity based on distance from camera
return 0.0f;
}
return value;
}
default:
{
return value;
}
}
}
This may help ypu.
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
if (view == nil)
{
NSString *strStarImg=[[yourarrayofImage objectAtIndex:index] valueForKey:#"keyofImage"];
ImgView = [UIImageView alloc] initWithImage:[UIImage imageNamed:strStarImg];
//you can define frame of your imageview here...ImgView.frame=CGRectMake(0, 450, 768, 462);
[view addSubview:img];
return view;
}
let me know it is working or not..!!
Happy Coding....!!!
I am new to IOS development. I want to create the view like the shown in Pic.
I also want that when user write in textfield and Keyboard appears TextField scrollup to Keyboard and should be hidden behind Key board.
thanks, Help please
You can not use a UITableViewController but a standard view controller and implement UITableViewDelegate and UITableViewDataSource and implement the necessary delegate methods in your controller, like cellForRowAtIndexPath.
This will allow you to have a table view and control it like you would with a UITableViewController and have any other interface elements you wish.
You would want to add the textfield and button inside of the footer. You can use keyboard notifications to move the view offset so that your textfield will be visible when the user is typing in the keyboard.
Footer:
*I'm assuming the textfield and send button are ivars.
// add footer to table
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 85.0f)];
if(yourTextField ==nil){
yourTextField = [[UITextField alloc] initWithFrame:CGRectMake(5,5,200,35)];
}
if(yourSendButton ==nil){
yourSendButton = [[UIButton alloc] initWithFrame:CGRectMake(225,5,75,35)];
yourSendButton addTarget:self action:#selector(sendBtnClicked) forControlEvents:UIControlEventTouchUpInside];
}
[footerView addSubview:yourTextField];
[footerView addSubview:yourSendButton];
[tableView setTableFooterView:footerView];
Here is some example code for moving the view for the keyboard:
- (void)keyboardWillShow:(NSNotification *)notification
{
NSValue *keyboardFrameValue = [[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardFrame = [[self view] convertRect:[keyboardFrameValue CGRectValue] fromView:nil];
NSNumber *duration = [[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey];
[UIView animateWithDuration:[duration floatValue] animations:^{
[scrollView setFrame:CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
keyboardFrame.origin.y - scrollView.frame.origin.y)];
}];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
NSNumber *duration = [[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey];
[UIView animateWithDuration:[duration floatValue] animations:^{
[scrollView setFrame:CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
self.view.frame.size.height - (iPhone ? 44.0f : 0.0f))];
}];
}
You will need to implement the UITableView's delegate methods:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
an example of adding a textfield to the footer would look something like:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
{
UIView* footer = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)] autorelease];
footer.backgroundColor = [UIColor whiteColor];
UITextField* field = [[[UITextField alloc] initWithFrame:CGRectMake(0, 0, 320, 44)] autorelease];
[field setBorderStyle:UITextBorderStyleBezel];
[footer addSubview:field];
return footer;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
{
return 44;
}
To get the keyboard will respond properly automatically - you just just need to resign the textfield when you are done with it.
What I am having right now is
View :
1.UILabel : show a text
2.A GMGridView : show a grid of views
The codes are
- (void)viewDidLoad
{
[super viewDidLoad];
gridViewHolder.itemSpacing = SPACING;
gridViewHolder.dataSource = self;
gridViewHolder.actionDelegate = self;
}
#pragma mark - GMGridViewDataSource
- (CGSize)GMGridView:(GMGridView *)gridView sizeForItemsInInterfaceOrientation:(UIInterfaceOrientation)orientation {
return CGSizeMake(WIDTH, HEIGT);
}
- (NSInteger)numberOfItemsInGMGridView:(GMGridView *)gridView {
return [needs count];
}
- (GMGridViewCell *)GMGridView:(GMGridView *)gridView cellForItemAtIndex:(NSInteger)index {
cell = [gridView dequeueReusableCell];
CGSize size = [self GMGridView:gridViewHolder sizeForItemsInInterfaceOrientation:UIInterfaceOrientationPortrait];
if (!cell)
cell = [[GMGridViewCell alloc] init];
UIView *innerView = [[UIView alloc] initWithFrame:CGRectMake(COOR_X, COOR_Y, size.width, size.height)];
innerView.backgroundColor = [UIColor grayColor];
cell.contentView = innerView;
return cell;
}
So now I can successfully to display a bunch of views in gridview. However, the content of the grid view will cover the label when I am scrolling the grid view. Below is the picture so that you can see my situation now
How can avoid this situation so that whenever I scroll up my gridview, its contents wont be overlapped with my uilabel
Try this:
gridview.clipsToBounds=TRUE;
You can insert the gridview below the label using insertSubview on the view.
[self.view insertSubview:gmGridView atIndex:0];
I have a UIPickerView that is populated by an NSMutableArray called sectionNamesArray. When an item is added to sectionNamesArray, how do I manually get this delegate to be called?
-- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return ([sectionNamesArray count] + 1);
}
The problem is that I add this pickerView to the center of a navBar in the titleView. If I try to nil the UIPickerView and reallocate it in order to hopefully get the delegate called again, the PickerView shows up on the left side of the navbar, instead of the center. I am guessing maybe the interface builder settings got it in the center...?
Here's the code for that:
-(void) setupPickerView{
myPickerView = nil;
myPickerView = [[UIPickerView alloc] init];
myPickerView.backgroundColor = [UIColor clearColor];
myPickerView.delegate = self;
myPickerView.dataSource = self;
myPickerView.showsSelectionIndicator = YES;
[self.navigationController.navigationBar setBackgroundView:myPickerView];
CGSize pickerSize = [myPickerView sizeThatFits:CGSizeZero];
UIView *pickerTransformView = [[UIView alloc] initWithFrame:CGRectMake(-40.0, -43.0, pickerSize.width, pickerSize.height)];
pickerTransformView.transform = CGAffineTransformMakeScale(.55f, .55f);
[pickerTransformView addSubview:myPickerView];
[self.navigationController.navigationBar setBackgroundView:pickerTransformView];
}
When you add something to your array can't you use [UIPickerView reloadAllComponents] or - (void)reloadComponent:(NSInteger)component?
That will most likely query your delegate and call everything necessary to check your array and reload the view.