Quick qeustion, my code:
if (slider2.value == 1)
{
barHeight = 100;
}
else if (slider2.value == 2)
{
barHeight = 200;
}
else if (slider2.value == 3)
{
barHeight = 300;
}
else if (slider2.value == 4)
{
barHeight = 400;
}
else if (slider2.value == 5)
{
barHeight = 500;
}
else
{
barHeight = 600;
}
When I drag the slider from 1 to 6 I see the height of the bar change. But when I move from 6 to 1 the barHeight is stuck at 600 and does not return to 100. What am I missing?
Edit ( full statement ):
- (void)valueAgeChanged:(UISlider*)slider2
{
// DRAW BARS (skeme)
CGRect frame = CGRectMake(595, barX, 80, barHeight);
orangeView= [[UIView alloc] initWithFrame:frame];
orangeView.backgroundColor = [UIColor orangeColor];
[self.view addSubview:orangeView];
// Let slider 1 animate on set value
[slider2 setValue:((int)((slider2.value + 1) / 1.0) - 1.0) animated:NO];
if (slider2.value == 1) {
barHeight = 100;
}else if (slider2.value == 2) {
barHeight = 200;
// barX = 300;
}else if (slider2.value == 3) {
barHeight = 300;
}else if (slider2.value == 4) {
barHeight = 400;
}else if (slider2.value == 5) {
barHeight = 500;
}else if (slider2.value == 6) {
barHeight = 600;
}
}
You're adding a new orangeView every time your value is changed. So they are simply overlaying each other. The tallest view will remain on screen and when you add shorter views of the same colour you won't see them.
To fix this you could set up the orangeView property outside of your valueChanged method (maybe viewDidLoad) and add it as a subview.
Then whenever your slider updates only update the frame of your view.
e.g.
- (void)valueAgeChanged:(UISlider*)slider2
{
[slider2 setValue:((int)((slider2.value + 1) / 1.0) - 1.0) animated:NO];
if (slider2.value == 1) {
barHeight = 100;
}else if (slider2.value == 2) {
barHeight = 200;
// barX = 300;
}else if (slider2.value == 3) {
barHeight = 300;
}else if (slider2.value == 4) {
barHeight = 400;
}else if (slider2.value == 5) {
barHeight = 500;
}else if (slider2.value == 6) {
barHeight = 600;
}
self.orangeView.frame = CGRectMake(595, barX, 80, barHeight);
}
You should also move this to after your if else statement, otherwise it will only update with the previous value.
EDIT:
As rmaddy points out the if statement is a bit overkill in this instance. A switch may be more readable/efficient, but as your barHeight is simply the slider value multiplied by 100 it would be much easier to write:
- (void)valueAgeChanged:(UISlider*)slider2
{
barHeight = floorf(slider2.value) * 100;
self.orangeView.frame = CGRectMake(595, barX, 80, barHeight);
}
Related
when I am adding UICollectionViewFlowLayout file with collection view. collectionViewCell height is not increasing according to the collection view. it takes spacing from the top and bottom:
- (void)awakeFromNib
{
[super awakeFromNib];
self.itemSize = CGSizeMake((self.collectionView.frame.size.width/2)+100,self.collectionView.frame.size.height );
//self.minimumInteritemSpacing = 10.0;
self.minimumLineSpacing = 10.0;
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sectionInset = UIEdgeInsetsMake(0, 30.0, 0, 30.0);
}
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
NSInteger itemsCount = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0];
// Imitating paging behaviour
// previous offset and scroll direction
if ((self.previousOffset > self.collectionView.contentOffset.x) && (velocity.x < 0.0f)) {
self.currentPage = MAX(self.currentPage - 1, 0);
} else if ((self.previousOffset < self.collectionView.contentOffset.x) && (velocity.x > 0.0f)) {
self.currentPage = MIN(self.currentPage + 1, itemsCount - 1);
}
// Update offset by using item size + spacing
CGFloat updatedOffset = (self.itemSize.width + 5) * self.currentPage;
self.previousOffset = updatedOffset;
return CGPointMake(updatedOffset, proposedContentOffset.y);
}
i have created sub class of UICollectionViewLayout.
I have a text field and used numberOfRowsInSection for creating more than 50 text fields. After that I use the if else condition, but it was time consuming and a lengthy method so I want to reduce my if else condition. I don't want to use the switch condition. What should I do?
if (textField.tag == 0)//cust add line 1
{
[_customerFormTableView setContentOffset : CGPointMake(0, 0)];
}
else if (textField.tag == 1)//cust add line 2
{
[_customerFormTableView setContentOffset : CGPointMake(0, 0)];
}
else if (textField.tag == 2)//kyc line 1
{
[_customerFormTableView setContentOffset : CGPointMake(0, 50)];
}
else if (textField.tag == 3)// kyc line 2
{
[self.view endEditing : YES];
DatePickerViewController *dateViewContrl = [self.storyboard instantiateViewControllerWithIdentifier : #"DatePickerViewController"];
dateViewContrl.delegate = self;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
{
//dateViewContrl.preferredContentSize=CGSizeMake(325, 200);
dateViewContrl.preferredContentSize = CGSizeMake(290, 200);
}
popcontrol = [[WYPopoverController alloc] initWithContentViewController:dateViewContrl];
[popcontrol.delegate self];
// _currentfield=_dateTextField;
NSLog(#"%f %f",popcontrol.popoverContentSize.height,popcontrol.popoverContentSize.height);
CGRect rect_ = [self.view convertRect : textField.frame fromView : textField.superview];
[popcontrol presentPopoverFromRect : rect_
inView : self.view
permittedArrowDirections : WYPopoverArrowDirectionAny
animated : YES
options : WYPopoverAnimationOptionScale];
return NO;
}
else if (textField.tag == 4)
{
[textField resignFirstResponder];
[self DropDownGendview : textField];
return NO;
}
else if (textField.tag == 5)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 250)];
}
else if (textField.tag == 6)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 310)];
}
else if (textField.tag == 7)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 370)];
}
else if (textField.tag == 8 || textField.tag == 13 || textField.tag == 20)
{
[self.view endEditing : YES];
[self DropDownview : textField];
return NO;
}
else if (textField.tag == 9)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 510)];
}
else if (textField.tag == 10)//cor email
{
[_customerFormTableView setContentOffset : CGPointMake(0, 630)];
}
else if (textField.tag == 11)//desig
{
[_customerFormTableView setContentOffset : CGPointMake(0, 700)];
}
else if (textField.tag == 12)//level
{
[_customerFormTableView setContentOffset : CGPointMake(0, 770)];
}
else if (textField.tag == 14)//level
{
[_customerFormTableView setContentOffset : CGPointMake(0, 910)];
}
else if (textField.tag == 15)//level
{
[_customerFormTableView setContentOffset : CGPointMake(0, 980)];
}
else if (textField.tag == 16)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1050)];
}
else if (textField.tag == 17)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1140)];
}
else if (textField.tag == 18)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1240)];
}
else if (textField.tag == 19)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1310)];
}
else if (textField.tag == 21)
{
NSLog(#"state dropdown %ld",(long)textField.tag);
}
else if (textField.tag == 22)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1520)];
}
else if (textField.tag == 23)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1590)];
}
else if (textField.tag == 24)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1660)];
}
else if (textField.tag == 25)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1730)];
}
else if (textField.tag == 26)
{
[self.view endEditing : YES];
[self dropDownPurposeView : textField];
return NO;
}
You can represent a lot of these if statements with data, using a struct:
typedef struct
{
int tag;
int pointX;
int pointY;
} Values;
const Values values[] = {
{0, 0, 0},
{1, 0, 0},
{2, 0, 50},
// etc
};
then iterate through values and determine if your tag is in it:
int i;
bool found = false;
for (i = 0; i < sizeof(values) / sizeof(values[0]); i++)
{
if (values[i].tag == textField.tag)
{
[_customerFormTableView setContentOffset: CGPointMake(values[i].pointX,
values[i].pointY)];
found = true;
break;
}
}
if (! found)
{
// do more complicated operations here
}
you can speed up the for statement with a binary search, if the tags are sorted.
You can try with switch case statement.It is better one instead of having lots of if else condition.If you use swit case it will improve your performance rather than having multiple if else condition.
A switch statement allows a variable to be tested for equality against a list of values. Each value is called a case, and the variable being switched on is checked for each switch
switch(expression){
case constant-expression :
statement(s);
break; /* optional */
case constant-expression :
statement(s);
break; /* optional */
/* you can have any number of case statements */
default : /* Optional */
statement(s);
}
Generally the expression used in a switch statement must have an integral or enumerated type or be of a class type in which the class has a single conversion function to an integral or enumerated type.
For more details go with this https://www.tutorialspoint.com/objective_c/switch_statement_in_objective_c.htm
I found this ingenious solution in stackoverflow. Unfortunately, this code does not work in my project. I try to divide a round SKSpriteNode in four different touch areas. I would also like to change the color of the area (Only when the area is pressed). Do you know perhaps how to do that?
For an example, or help I am very grateful.
My code:
- (void)setUpDPad {
_dPad = [SKSpriteNode spriteNodeWithImageNamed:#"dpad"];
_dPad.anchorPoint = CGPointMake(0.0, 0.0);
_dPad.position = CGPointMake(0.0-self.frame.size.width/2+5, 0.0-self.frame.size.height/2+50);
_dPad.zPosition = 1;
[self addChild:_dPad];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
CGFloat angle = [self angleToPoint:location];
int area = [self sectionForAngle:angle];
if ([_dPad containsPoint:location]) {
if (area == 1) {
}
if (area == 2) {
}
if (area == 3) {
}
if (area == 4) {
}
}
}
}
- (float)angleToPoint:(CGPoint)tapPoint {
int x = _dPad.frame.size.width/2;
int y = _dPad.frame.size.height/2;
float dx = tapPoint.x - x;
float dy = tapPoint.y - y;
CGFloat radians = atan2(dy,dx);
CGFloat degrees = radians * 180 / M_PI;
if (degrees < 0) return fabs(degrees);
else return 360 - degrees;
}
- (int)sectionForAngle:(float)angle {
if (angle >= 45 && angle < 135) {
return 1;
}
else if (angle >= 135 && angle < 225) {
return 2;
}
else if (angle >= 225 && angle < 315) {
return 3;
}
else {
return 4;
}
}
When scrolling content in Safari, the title bar animates to a smaller version of its self. What is the best way to implement this?
Currently, I am changing the size of the frame like so:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//
// Table view
//
CGFloat currentPosition = scrollView.contentOffset.y - CGRectGetHeight(self.tableView.tableHeaderView.frame) + CGRectGetHeight(self.navigationController.navigationBar.frame) + CGRectGetHeight([[UIApplication sharedApplication] statusBarFrame]);
if ([scrollView isKindOfClass:[HeadlinesHeadlinesTableView class]]) {
ScrollDirection scrollDirection;
if (self.lastContentOffset > scrollView.contentOffset.y) {
scrollDirection = ScrollDirectionDown;
} else if (self.lastContentOffset < scrollView.contentOffset.y) {
scrollDirection = ScrollDirectionUp;
}
self.lastContentOffset = scrollView.contentOffset.y;
CGRect frame = self.navigationController.navigationBar.frame;
CGFloat minimumFrameHeight = 30.0f;
CGFloat maximumFrameHeight = 44.0f;
CGFloat titleSize = [[self.navigationController.navigationBar.titleTextAttributes objectForKey:NSFontAttributeName] pointSize];
CGFloat minimumTitleHeight = 22.0f;
CGFloat maximumTitleHeight = 30.0f;
if (currentPosition > 0 && CGRectGetHeight(frame) >= minimumFrameHeight && CGRectGetHeight(frame) <= maximumFrameHeight) {
switch (scrollDirection) {
case ScrollDirectionUp:
frame.size.height--;
titleSize--;
break;
case ScrollDirectionDown:
frame.size.height++;
titleSize++;
break;
default:
break;
}
if (CGRectGetHeight(frame) <= minimumFrameHeight) {
frame.size.height = minimumFrameHeight;
}
if (CGRectGetHeight(frame) >= maximumFrameHeight) {
frame.size.height = maximumFrameHeight;
}
if (titleSize <= minimumTitleHeight) {
titleSize = minimumTitleHeight;
}
if (titleSize >= maximumTitleHeight) {
titleSize = maximumTitleHeight;
}
}
[self.navigationController.navigationBar setFrame:frame];
[self.navigationController.navigationBar setTitleTextAttributes: #{ NSFontAttributeName : [UIFont fontWithName:#"Canterbury-Regular" size:titleSize] }];
}
}
Naturally, this way is not smooth and a lot of code, not to mention the fact that I need to fade out bar button items as well.
Thanks in advance!
Take a look at AMScrollingNavbar, it already has fading support.
You can try to change font size of NavigationBar to make the title smaller.
How can I access hyperlinks in PDF documents on the iPhone and iPad?
I want to set links on the content of an e-book.
Use following function to put UIButtons on the links in PDF. This will draw Buttons on your UIView. You have to pass your page as parameter. Currently it will draw button with type UIButtonTypeRoundedRect you change afterwards it to custom so it will be hidden. Initially buttons may be drawn other place than link so you need to adjust x/y position according to you requirement.
-(void)drawLinks:(CGPDFPageRef)thisPage
{
CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(thisPage);
CGPDFArrayRef outputArray;
if(!CGPDFDictionaryGetArray(pageDictionary,"Annots", &outputArray))
{
return;
}
int arrayCount = CGPDFArrayGetCount( outputArray );
if(!arrayCount)
{
//continue;
}
for( int j = 0; j < arrayCount; ++j )
{
CGPDFObjectRef aDictObj;
if(!CGPDFArrayGetObject(outputArray, j, &aDictObj))
{
return;
}
CGPDFDictionaryRef annotDict;
if(!CGPDFObjectGetValue(aDictObj, kCGPDFObjectTypeDictionary, &annotDict)) {
return;
}
CGPDFDictionaryRef aDict;
if(!CGPDFDictionaryGetDictionary(annotDict, "A", &aDict)) {
return;
}
CGPDFStringRef uriStringRef;
if(!CGPDFDictionaryGetString(aDict, "URI", &uriStringRef)) {
return;
}
CGPDFArrayRef rectArray;
if(!CGPDFDictionaryGetArray(annotDict, "Rect", &rectArray)) {
return;
}
int arrayCount = CGPDFArrayGetCount( rectArray );
CGPDFReal coords[4];
for( int k = 0; k < arrayCount; ++k ) {
CGPDFObjectRef rectObj;
if(!CGPDFArrayGetObject(rectArray, k, &rectObj)) {
return;
}
CGPDFReal coord;
if(!CGPDFObjectGetValue(rectObj, kCGPDFObjectTypeReal, &coord)) {
return;
}
coords[k] = coord;
}
char *uriString = (char *)CGPDFStringGetBytePtr(uriStringRef);
NSString *uri = [NSString stringWithCString:uriString encoding:NSUTF8StringEncoding];
CGRect rect = CGRectMake(coords[0],coords[1],coords[2],coords[3]);
CGPDFInteger pageRotate = 0;
CGPDFDictionaryGetInteger( pageDictionary, "Rotate", &pageRotate );
CGRect pageRect = CGRectIntegral( CGPDFPageGetBoxRect( thisPage, kCGPDFMediaBox ));
if( pageRotate == 90 || pageRotate == 270 )
{
CGFloat temp = pageRect.size.width;
pageRect.size.width = pageRect.size.height;
pageRect.size.height = temp;
}
rect.size.width -= rect.origin.x;
rect.size.height -= rect.origin.y;
CGAffineTransform trans = CGAffineTransformIdentity;
trans = CGAffineTransformTranslate(trans, 0, pageRect.size.height);
trans = CGAffineTransformScale(trans, 1.0, -1.0);
rect = CGRectApplyAffineTransform(rect, trans);
UIButton *btnTmp = [UIButton buttonWithType:UIButtonTypeRoundedRect]; // After testing put here UIButtonTypeCustom
[btnTmp addTarget:self action:#selector(urlOpen:) forControlEvents:UIControlEventTouchUpInside];
rect.origin.x = rect.origin.x + 78; //I have adjusted this as per my requirement
rect.origin.y = rect.origin.y + 108; // I have adjusted this as per my requirement
btnTmp.frame = rect;
btnTmp.titleLabel.text = uri;
[self.superview addSubview:btnTmp];
}
}