I'm a beginner in iOS programming and I'm looking for an answer to my question.
I have a UISlider inside a UITableViewCell and I'm trying to get this disposition: Label-Slider-DetailLabel(dynamic).
This is my code :
cell = [tableView dequeueReusableCellWithIdentifier:#"SelectedMeetingCell"];
[cell.textLabel setText:#"Duration"];
[cell.detailTextLabel setText:[Utilities StringFromDuration:Agenda.InitialDuration.doubleValue]];
sliderCell = (SliderCell*)[[UIViewController alloc] initWithNibName:#"SliderCell" bundle:nil].view;
[sliderCell setDelegate:self];
[sliderCell.slider setValue:Agenda.InitialDuration.doubleValue];
[cell.contentView addSubview:sliderCell];
sliderCell.slider.frame = CGRectMake(100, 0, 500, 44);
The last line is the way I used to place my slider the way I wanted to be. It works great for iPad but not at all for the iPhone version. Is there any way to resize the width of my slider automatically depending on the device ?
(SliderCell is a UITableViewCell with a UISlider #property)
Thank you all in advance!
Instead of hard coding the values, you could get the container views width and set the sliders width as a percentage of it.
CGRect superViewFrame = slider.superView.frame;
CGRect sliderFrame = slider.frame;
sliderFrame.size.width = <your choice for eg, superViewFrame.size.width * 0.3f>
sliderFrame.origin.x = <your choice for eg, superViewFrame.size.width * .2f>
slider.frame = sliderFrame;
you can get the size of a device by calling self.view
sliderCell.slider.frame = CGRectMake(100, 0, self.view.frame.size.width, self.view.frame.size. height);
after you may want to subtract or divide depending on your view's size
Related
I have a UIDatepicker where i have added border image so that it sits on top of UIDatepicker border . In simulator the border image is in exactly on top of UIDatepicker border ,but when i run the project on iphone / ipod device .the border image tends to be in out of position .Why is this happening ?
When i tap on settingsButton ..settingsButtonChanged method is called and in settingsView datepicker is added .
Thanks
UPDATE :
-(void)viewDidLoad
{
userTimePicker = [[UIDatePicker alloc]init
}
-(IBAction)settingsButtonChanged:(UIButton *)sender
{
UIImageView *settingsImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"settingsViewImage.png"]];
settingsImage.frame = CGRectMake(0.0, 0.0, 280.0, 370.0);
CGFloat height = [UIScreen mainScreen].bounds.size.height;
if(height==568.00)
{
settingsView.frame = CGRectMake(0.0, 50.0, 280.0, 370.0);
}else
{
settingsView.frame = CGRectMake(20.0, 45.0, 280.0, 370.0);
}
settingsView.backgroundColor = [UIColor clearColor];
[settingsView addSubview:settingsImage];
UIImageView *userTimePickerBorder = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"datepickerBorder.png"]];
userTimePickerBorder.frame = CGRectMake(0.0, 0.0, 150.0, 180.0);
userTimePicker.frame = CGRectMake(65.0, 165.0, 150.0, 180.0);
userTimePicker.datePickerMode = UIDatePickerModeTime;
[settingsView addSubview:userTimePicker];
[userTimePicker addSubview:userTimePickerBorder];
[symptomView addSubview:settingsView];
}
Suggestion 1
Well, first of all, this code makes no sense at all:
- (void)viewDidLoad {
userTimePicker = [[UIDatePicker alloc]init];
}
Consider what that does. Suppose you have a property or instance variable called userTimePicker (you must have something like that, right?). Now, either it is an outlet pointing to an actual date picker coming from the nib/storyboard, or it isn't. Well then:
If it is, now it isn't! You've just overwritten the reference to the actual date picker in the interface with a different date picker.
If it isn't, you've just set userTimePicker to a date picker, but that date picker is not in the interface (you have no code adding it to the interface).
So, either way, from now on, userTimePicker is useless; it does not point to anything in the interface.
So you would certainly need to fix that before doing anything else!
Suggestion 2
Also, I have a suggestion for why your results on the simulator differ from your results on the device: it might be because you've been testing repeatedly on the simulator. This can cause old code/resources to be present in the simulator version of your app. To fix that, clean out your caches and restore the simulator to its defaults, as I describe here: https://stackoverflow.com/a/6247073/341994 I'm hoping that will at least cause the simulator and the device to behave the same! And then you can get on with the real business of fixing your code.
Suggestion 3
This code is really weird:
CGFloat height = [UIScreen mainScreen].bounds.size.height;
if(height==568.00)
{
settingsView.frame = CGRectMake(0.0, 50.0, 280.0, 370.0);
}else
{
settingsView.frame = CGRectMake(20.0, 45.0, 280.0, 370.0);
}
You should not be consulting the screen bounds for anything! All of this should be taking place within some view controller. The view controller's view should rotate and resize to fit the device orientation or screen size, so the bounds of the view controller's view will change, and that is what you should should be checking.
And instead of hard-coding those frame values, you should express them in terms of the view controller view's bounds, or the bounds of the superview they are to go into. That will give you consistent results. Even better, if this is on iOS 6, use constraints instead of setting frames.
I'm trying to rotate a label on my view 90 degrees. I've tried the two following ways to do it and the label just disappears from the screen. I triple checked that the properties are properly attached. Any thoughts?
attempt one:
// rotating labels 90 degrees
self.labelCloseScroll.transform = CGAffineTransformMakeRotation (3.14/2);
attempt two:
CGAffineTransform rotate = CGAffineTransformMakeRotation(3.14/2);
rotate = CGAffineTransformScale(rotate, 1, 1);
[self.labelCloseScroll setTransform:rotate];
I am not 100% sure if it works or not but why are you not using M_PI_2. It's just simple thought that you are assuming Value of Pi to be 3.14 but the exact value is 3.14159...
I did it like this and it worked fine :
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 50, 70)];
lbl.text = #"New";
lbl.backgroundColor = [UIColor clearColor];
lbl.textColor = [UIColor whiteColor];
lbl.highlightedTextColor = [UIColor blackColor];
lbl.font = [UIFont systemFontOfSize:12];
lbl.transform = CGAffineTransformMakeRotation(M_PI_2);
[self.view addSubview:lbl];
You can also check Answers from these Questions :
How to Render a rotated UIlabel
Rotating UILabel at its center
Hope it will be helpful for you.
It may simply be that the view's bounds have become too small for the text. When the text can't be fully displayed in label view in iOS, it simply disappears, rather than remaining on show. Perhaps it's a deliberate Apple policy to prevent apps shipping with clipped text and forcing the dev to fix ;)
It sounds very much as though this is what is happening. You have said the text gets smaller as you rotate it, which indicates you have the shrink text to fit property set on the label view. This will shrink the text as the constraining view reduces in size. But the text will only shrink so much before it disappears.
If the label view itself would seem to be big enough, also be sure to check the bounds of each parent view the label is contained in, up through the view hierarchy.
I'm coding a custom UITableViewCell object and I've implemented layoutSubviews to resize the cell when its contents is updated.
To implement heightForRowAtIndexPath, I'm calculating the height of the cell within the custom UITableViewCell object. I'm using NSString sizeWithFont to calculate the size of the cell based on the text within a UILabel and the width of a cell in the UITableView.
But how do I get the width of a cell in the UITableView?
Right now, I'm passing in the table view to the object and using the frame. But the width is of the whole table not the individual cells. Is there something I'm missing here?
Thanks in advance.
EDIT3
I was thinking, if it's really not possible, just test portrait or landscape orientation then set the width manually (ipad just has 2 different orientations)..
EDIT2
There have been some questions about 'why are you doing it this way xxxx'. I understand maybe there's a better way to achieve what I'm doing, creating a custom cell that can calculate its own height with varying text length. If there's a better way of doing it I'm all ears :)
EDIT
http://img845.imageshack.us/img845/7792/screenshot20121129at193.png
+ (CGFloat)getHeightForCellWithText:(NSString *)text isExpanded:(BOOL)expanded tableView:(UITableViewController *)tv {
ProposalViewCell *cell = [[ProposalViewCell alloc] initWithStyle:UITableViewCellSelectionStyleNone reuseIdentifier:#"NormalCell" tableView:tv];
[cell setLabelText:text];
[cell setExpanded:expanded];
[cell layoutSubviews];
return cell.primaryLabel.frame.size.height + cell.readmoreButton.frame.size.height + cell.sendmessageButton.frame.size.height +30;
}
- (void)layoutSubviews {
[super layoutSubviews];
_primaryLabel.numberOfLines = 0; // multiple lines
// size of expanded text label
// sizeWithFont: if text doesn't fit, it is truncated
CGSize expandedSize = [_primaryLabel.text sizeWithFont:myFont constrainedToSize:CGSizeMake(tableView.view.frame.size.width, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];
// size as expanded by default
_primaryLabel.frame = CGRectMake(10, 10, expandedSize.width, expandedSize.height);
if (expanded==NO) {
// size of summary text label
_primaryLabel.numberOfLines = 10;
CGSize summarySize = [_primaryLabel sizeThatFits:_primaryLabel.frame.size];
_primaryLabel.frame = CGRectMake(10, 10, summarySize.width, summarySize.height);
}
_readmoreButton.frame = CGRectMake(10, _primaryLabel.frame.size.height+10, 225, 25);
_sendmessageButton.frame = CGRectMake(10, _primaryLabel.frame.size.height+10+_readmoreButton.frame.size.height+10, 225, 25);
}
To get the width of the cell just do this...
cell.contentview.frame.size.width
I have scroll view with label and a table view and a button . I just want to scroll the scrollview and the table view must display all the contents but tableview must not scroll. Below the tableview i have a button. How to set the frame of the button so it comes exactly below the table?
Thanks
Maybe you would like to set the YourTableView.userInteractionEnabled = NO?
Yes we can disable the scrolling the tableview.
Goto->xib->select table->Goto 1st tab->unselect the scrolling Enabled.
The answer for your Second Question.
Put the UiView in footer of your table and then place the button in that UIView you want to show in bottom.
It will always show at the bottom.
If you want to place button programmatically use following code in viewDidload method.
///--------Table Footer is Set here
UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 260, 44)];
UIButton *adddays = [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 260, 44)];
[adddays setBackgroundImage:[UIImage imageNamed:#"abcd.png"] forState:UIControlStateNormal];
[adddays addTarget:self action:#selector(buttonaction) forControlEvents:UIControlEventTouchDown];
UILabel *text = [[UILabel alloc] initWithFrame:CGRectMake(75, 12, 250, 20)];
[text setBackgroundColor:CLEAR_COLOR];
[text setText:#"Title for your button"];
[text setTextColor:XDARK_BLUE];
text.font=[UIFont fontWithName:#"Arial-BoldMT" size:18.0f];
[footer addSubview:adddays];
[footer addSubview:text];
[table setTableFooterView:footer];
This is assuming you have created IBOutlets for your scrollView, tableView and button, and hooked them up appropriately.
I find it useful to remember that we're only messing with the y-values of a CGRect (origin.y & size.height) - The x-values should be set up in the xib.
I've commented this profusely to illustrate my point better, usually I would only comment where appropriate
-(void)viewDidLoad {
[self.tableView setScrollEnabled:NO];
// Get the number of rows in your table, I use the method
// 'tableView:numberOfRowsInSection:' because I only have one section.
int numOfRows = [self.tableView numberOfRowsInSection:0];
// Get the height of your rows. You can use the magic
// number 46 (44 without including the separator
// between rows) for the height of your rows, but because
// I was using a custom cell, I had to declare an instance
// of that cell and exctract the height from
// cell.frame.size.height (adding +2 to compensate for
// the separator). But for the purpose of this demonstration
// I'm going to stick with a magic number
int rowHeight = 46; //Eww, Magic numbers! :/
// Get a reference to the tableViews frame, and set the height
// of this frame to be the sum of all your rows
CGRect frame = self.tableView.frame;
frame.size.height = numOfRows * rowHeight;
// Now we have a frame with the exact size of our table,
// so set the 'tableView.frame' AND the 'tableView.contentSize'
// to that. (Because we want ALL rows visible as you
// disabled scrolling for the 'tableView')
self.tableView.frame = frame;
self.tableView.contentSize = frame.size;
// Now we want to set up the button beneath the table.
// We still have the 'frame' variable, which gives us
// the tableView's Y-origin and height. We just add these
// two together (with +20 for padding) to get the origin of the button
CGRect buttonFrame = self.button.frame;
buttonFrame.origin.y = frame.origin.y + frame.size.height + 20;
self.button.frame = buttonFrame;
// Finally, we want the `scrollView`'s `contentSize` to
// encompass this entire setup (+20 for padding again)
CGRect scrollFrame = self.scrollView.frame;
scrollFrame.size.height = buttonFrame.origin.y + buttonFrame.size.height = 20;
self.scrollView.contentSize = scrollFrame.size;
}
You could stop the scrolling the table view. But you shouldn't be adding a tableview inside a scrollview. UITableView is subclass of UIScrollView and adding one scrollView on another will create problem. I suggest you to remove the scrollview and use the tableview alone ( as the tableview itself is a scrollview).
I have some code that creates a table cell with a slider. It's pretty straightforward and it sizes well on the iPhone. I've anonymized it a bit here:
UITableViewCell* cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Foo"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
CGRect contentViewFrame = cell.contentView.frame;
CGRect sliderFrame = CGRectMake(10, 0, 280, contentViewFrame.size.height);
UISlider* slider = [[UISlider alloc] initWithFrame:sliderFrame];
UIImage* minimumImage = [UIImage imageNamed:#"min.png"];
UIImage* maximumImage = [UIImage imageNamed:#"max.png"];
slider.minimumValueImage = minimumImage;
slider.maximumValueImage = maximumImage;
slider.value = 0.5f;
[slider addTarget:self action:#selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
[cell.contentView addSubview:slider];
[slider release];
Of course, this is incorrectly sized for the iPad. So my first thought was to set the autoresizingMask property to UIViewAutoresizingFlexibleWidth. Problem solved, right? Nope. Now on the iPhone, the width of the slider-plus-images content is less than 280 and so it doesn't go right to the end -- it ends up about 20 pixels short.
On the iPad, the same thing -- the width of the UISlider automatically resizes to about 20 pixels short of the end of the cell.
Perhaps the auto resize flag is paying attention to the non-existent accessoryView of the cell? I tried setting it to nil explicitly, but I think it's nil by default, so nothing changed.
I'd like this cell's content to resize automatically to be the "full" width of the cell, regardless of device and orientation. Is there an easy way to do this?
It works exactly how you described. I am inclined to think it's iOS bug. On iPAD when you create new UITableViewCell its width set for 320. hardcoded(!) both view and contentView. It does not resize properly if set to UIViewAutoresizingFlexibleWidth. I had it set to view.frame.size.width/2 with funny results: on iPhone it's 160, on iPad it's 608!!!
I ended up manually resizing my cells and their content.
Bit late but i found the solution of the same question today, but you need to create a custom UITableViewCell.
Then you can overwrite the function
- (void) layoutSubviews
{
[dateLabel setFrame:CGRectMake(10.f, 16.f, 80.f, 12.f)];
[textLabel setFrame:CGRectMake(106.f, 16.f, contentView.frame.size.width-105.f + 1.f, 12.f)];
}
In that function the self.frame.size.width is the actual one.
And it works with rotation of the device, too.
You should be able to tell the resizing system to "stick" the object a fixed distance from the right edge (where it's not resizing far enough). If you experiment with IB you can create a view that resizes in width and is fixed to the right side.
Do you have UIViewAutoresizingFlexibleRightMargin set as well?
Set your cell's contentMode to UIViewContentModeRedraw.