Resizing start behaving inaccurate after starting loop of scrolling - ios

i got images scrollview and i am trying to change the size of views while scrolling, it works correct first time but when i started loop of scrolling means setting contentoff 0, 0, then it will start behaving inaccurate, means it started shuffeling views, up and down, it is working fine while scrolling upwards. if anyone get the problem please guide me where i am doing wrong? or suggest me any tutorial. HERE IS MY CODE.
- (void)viewDidLoad{
if (IS_IPHONE5)
scroller.contentSize=CGSizeMake(320, ((count*142)+710));
else
scroller.contentSize=CGSizeMake(320, ((count*130)+530));
makecopy= tableArray.count+4;
for(int i=0;i<=makecopy;i++)
{
if(i==0)
yValue=0;
else
yValue=130;
UIView* view1;
//=[[UIView alloc]initWithFrame:CGRectMake(0, (i*130)+yValue, 320, 260)];
if (IS_IPHONE5) {
if (i!=0/*&&i!=count*/){
yValue=142;
view1=[[UIView alloc]initWithFrame:CGRectMake(0, (i*142)+yValue, 320, 284)];
}
else{
yValue=0;
view1=[[UIView alloc]initWithFrame:CGRectMake(0, (i*142)+yValue, 320, 284)];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ([[UIScreen mainScreen] bounds].size.height == 568)
{
if (normalScroll)
{
for(int i=0;i<count;i++)
{
// NSLog(#">:%i %i:<",(i*142),((i+1)*142));
if (scroller.contentOffset.y>=(i*142)&&scroller.contentOffset.y<((i+1)*142)){
[self doscrollingwiththView:[scroller viewWithTag:i+1] view2:[scroller viewWithTag:i+2] view3:[scroller viewWithTag:i+3] view4:[scroller viewWithTag:i+4]];
}
}
changeMe = true;
if (!isUp && scrollView.contentOffset.y>(count*142)) {
[scrollView setContentOffset:CGPointMake(0, 0)];
changeMe = false;
}
if (isUp && scrollView.contentOffset.y<= -1) {
[scrollView setContentOffset:CGPointMake(0, (count*142)-10)];
changeMe = false;
}
}
-(void)doscrollingwiththView:(UIView*)view1 view2:(UIView*)view2 view3:(UIView*)view3 view4:(UIView*)view4
{
// NSLog(#"view1 : %# view1 : %# view1 : %# view1 : %# ",view1,view2,view3,view4);
offsetY=offsetY1+ scroller.contentOffset.y;
int view1Y=0;
int view2Y=0;
//int view3Y;
//int view4Y;
if (IS_IPHONE5)
{
view2Y=284;
}
else
{
view2Y=260;
//view3Y=390;
//view4Y=520;
}
for(int i=0;i<makecopy;i++)
{
if (IS_IPHONE5) {
// NSLog(#"the value is: %i the contentoffset is:%f",(142*i),scroller.contentOffset.y);
if(scroller.contentOffset.y>=(142*i)&&scroller.contentOffset.y<(142*(i+1)))
{
view1Y=(142*i);
view2Y=284+(142*i);
}
}
else
{
if (scroller.contentOffset.y>=(130*i)&&scroller.contentOffset.y<(130*(i+1)))
{
view1Y=(130*i);
view2Y=260+(130*i);
}
}
}
if (IS_IPHONE5) {
view1.frame=CGRectMake(0, view1Y-(offsetY%142), 320, 284);
view2.frame=CGRectMake(0, view2Y-(offsetY%142), 320, 284);
view3.frame=CGRectMake(0, 426+view1Y, 320, 284);
view4.frame=CGRectMake(0, 568+view1Y, 320, 284);
NSLog(#"the content offset is: %d",offsetY);
}
else
{
view1.frame=CGRectMake(0, view1Y-(offsetY%130), 320, 260);
view2.frame=CGRectMake(0, view2Y-(offsetY%130), 320, 260);
view3.frame=CGRectMake(0, 390+view1Y, 320, 260);
view4.frame=CGRectMake(0, 520+view1Y, 320, 260);
}
}

what i understood by your code is, you are shifting the images while scrolling and resizing it to when it reaches some specific point as you r doing its top i think, then my friend you r making 4 view and i think there are 3 views at a time shown in screen, what you hav to do is make 5 view instead of making 4 views, and revolve these view and let me know after it, i hope it will work in your case.

Related

iOS 11.2 custom navigation bar infinite loop

Since the release of IOS 11.2 my app is encountering an infinite loop when pushing a view controller whose navigation controller has a custom navigation bar height. Did someone find the solution for this problem? Thanks.
-(void)layoutSubviews{
[super layoutSubviews];
float height = 42.5;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
height = 48;
}
imageView.frame = CGRectMake(0, 0, [[UIScreen mainScreen]bounds].size.width, height);
if(UI_USER_INTERFACE_IDIOM() ==UIUserInterfaceIdiomPad){
if(#available(iOS 11.0,*)){
self.frame =CGRectMake(0, 20,[[UIScreen mainScreen]bounds].size.width, 55); // this line provoke the infinite loop
for(UIView *aView in self.subviews){
if([NSStringFromClass([aView class]) isEqualToString: #"_UINavigationBarContentView"]){
aView.frame = CGRectMake(0, 10, aView.frame.size.width, aView.frame.size.height);
}
if([NSStringFromClass([aView class]) isEqualToString: #"_UIBarBackground"]){
aView.frame = CGRectMake(0, 0, aView.frame.size.width, self.frame.size.height );
}
}
}
}
}
I also had the same problem.
I solved by removing this
frame.size.height = customHeight
from layoutSubviews and then adding this
override var frame: CGRect {
get {
return CGRect(x: 0, y: 0, width: super.frame.width, height: customHeight)
}
set (value) {
super.frame = value
}
}
to my UINavigationBar subclass.
I left all other code in layoutSubviews as it was before. (nb)

Grouped Bar chart with JBChartView library

I've needed to draw a grouped bar charts in an iOS Projects I'm doing. So the iOS Third party library I used is JBChartView from Jawbone.
Up to the knowledge I gained with my research regarding this I found no any already supported ways within the library.
However I tried doing something like as follows:
- (NSUInteger)numberOfBarsInBarChartView:(JBBarChartView *)barChartView
{
return [self.chartLegend count]; // number of bars in chart "BB", "HB", "FB", "RO"
}
- (CGFloat)barChartView:(JBBarChartView *)barChartView heightForBarViewAtIndex:(NSUInteger)index
{
CGFloat height = (isnan((([[chartData objectAtIndex:index] doubleValue]/total)*100))) ? 0.0 : (([[chartData objectAtIndex:index] doubleValue]/total)*100);
NSLog(#"height : %f", height);
return height;
}
- (UIView *)barChartView:(JBBarChartView *)barChartView barViewAtIndex:(NSUInteger)index {
CGFloat height = (isnan((([[chartData objectAtIndex:index] doubleValue]/total)*100)))
? 0.0
: (([[chartData objectAtIndex:index] doubleValue]/total)*100);
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 50, height)];
[view setBackgroundColor:[UIColor grayColor]];
UIView *firstHalf = [[UIView alloc] initWithFrame:CGRectMake(0, height, 25, height)];
[firstHalf setBackgroundColor:[UIColor redColor]];
UIView *secondHalf = [[UIView alloc] initWithFrame:CGRectMake(25, height, 25, height/2)];
if (index == 0) {
[secondHalf setBackgroundColor:UIColorFromRGB(0xF15854)];
} else if (index == 1) {
[secondHalf setBackgroundColor:UIColorFromRGB(0x5DA5DA)];
} else if (index == 2) {
[secondHalf setBackgroundColor:UIColorFromRGB(0xFAA43A)];
} else if (index == 3) {
[secondHalf setBackgroundColor:UIColorFromRGB(0x60BD68)];
}
[view addSubview:firstHalf];
[view addSubview:secondHalf];
return view;
}
Note: Please, ignore the data values which I've put to determine the heights of the Red color and other varying color bars. And UIColorFromRGB is a custom methods I use in my development.
But it gives the graph as follows:
But what I really want to draw using JBChartView library is as follows:
Any help is accepted with loads of gratitude and respect, but except don't suggest to use any other library to get this done. I like the simplicity of JBChartView library. :-)
Thanks in advance!
From what I've found out, this is not possible using standard way, but can be worked around. See https://github.com/Jawbone/JBChartView/issues/139

Add hidden UIView to UITableView similar to UIRefreshControl

Very similar to a UIRefreshControl, I'm trying to put a UIView on top of a UITableView. Dragging down the table view should reveal the view and have it stay there. Dragging up should hide it again and then scroll the table view. When hidden the table view should scroll normally. Scrolling back to the top should either reveal the hidden view again, or snap to the hidden state. Ultimately the revealed view should contain some buttons or a segmented control. It should look and behave very similar to the OmniFocus App.
Hidden View in OmniFocus
Revealed View in OmniFocus
This is how far I got. Especially the snapping back to the hidden state when the table view scrolls back up does not work. If you time it right you'll end up stuck in the middle of top view, which is exactly not what I want.
static CGFloat const kTopViewHeight = 40;
#interface ViewController ()
#property (nonatomic, weak) UIView *topView;
#property (nonatomic, assign) CGFloat dragStartY;
#end
#implementation ViewController
#pragma mark - View Lifecycle
- (void)viewDidLoad
{
CGRect topViewFrame = CGRectMake(0.0, -kTopViewHeight, 320, kTopViewHeight);
UIView *myView = [[UIView alloc] initWithFrame:topViewFrame];
myView.backgroundColor = [UIColor greenColor]; // DEBUG
self.topView = myView;
[self.tableView addSubview:myView];
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
NSLog(#"scrollViewWillBeginDragging %#", NSStringFromCGPoint(scrollView.contentOffset));
self.dragStartY = scrollView.contentOffset.y;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSLog(#"scrollViewDidScroll %#", NSStringFromCGPoint(scrollView.contentOffset));
if (scrollView.contentOffset.y > 0) {
// reset the inset
scrollView.contentInset = UIEdgeInsetsZero;
} else if (scrollView.contentOffset.y >= -kTopViewHeight) {
// set the inset for the section headers
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y < -kTopViewHeight) {
// don't scroll further when the topView's height is reached
scrollView.contentInset = UIEdgeInsetsMake(-kTopViewHeight, 0, 0, 0);
scrollView.contentOffset = CGPointMake(0, -kTopViewHeight);
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
NSLog(#"scrollViewDidEndDragging %#", NSStringFromCGPoint(scrollView.contentOffset));
CGFloat yOffset = scrollView.contentOffset.y;
if (yOffset < 0) {
BOOL dragDown = self.dragStartY > yOffset;
CGFloat dragThreshold = 10;
if (dragDown) {
if (yOffset <= -dragThreshold) {
[self snapDown:YES scrollView:scrollView];
} else {
[self snapDown:NO scrollView:scrollView];
}
} else if (!dragDown) {
if (yOffset >= dragThreshold - kTopViewHeight) {
[self snapDown:NO scrollView:scrollView];
} else {
[self snapDown:YES scrollView:scrollView];
}
}
}
}
- (void)snapDown:(BOOL)down scrollView:(UIScrollView *)scrollView
{
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionBeginFromCurrentState
animations:^{
if (down) {
// snap down
scrollView.contentOffset = CGPointMake(0, -kTopViewHeight);
scrollView.contentInset = UIEdgeInsetsMake(kTopViewHeight, 0, 0, 0);
} else {
// snap up
scrollView.contentOffset = CGPointMake(0, 0);
scrollView.contentInset = UIEdgeInsetsZero;
}
}
completion:nil];
}
//paging for data you can use this spinner
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner stopAnimating];
spinner.hidesWhenStopped = NO;
spinner.frame = CGRectMake(0, 0, 320, 44);
tblView.tableFooterView = spinner;
tblView.tableFooterView.hidden = YES;
#pragma mark Table pull to refresh data....
- (void)scrollViewDidEndDragging:(UIScrollView *)aScrollView
willDecelerate:(BOOL)decelerate{
CGPoint offset = aScrollView.contentOffset;
CGRect bounds = aScrollView.bounds;
CGSize size = aScrollView.contentSize;
UIEdgeInsets inset = aScrollView.contentInset;
float y = offset.y + bounds.size.height - inset.bottom;
float h = size.height;
float reload_distance = 50;
if(y > h + reload_distance && _nextPage) {
NSLog(#"load more data");
tblView.tableFooterView.hidden = NO;
// index for new page of data will increment here
index = index + 1;
[spinner startAnimating];
[self performSelector:#selector(requestData) withObject:nil afterDelay:1.0f];
}
}
// when you request for data and wants to stop spinner
CGPoint offset = tblView.contentOffset;
// if new page is there set bool
_nextPage = YES;
// want to remove spinner
tblView.tableFooterView.hidden = YES;
[spinner stopAnimating];
[tblView setContentOffset:offset animated:NO];

How can I make UIScrollView/UIPageControl infinite?

I have created a simple image scrolling with UIPageControl and UIScrollView, I have three pages ! so what I need is when user scrolls page 0 to left , actually scroll should move to the page 3 and vice versa . I have checked Apple sample code but it was so complicated !, here is my codes :
- (void)setupScrollView {
_pageControl.currentPage = 0;
_pageControl.numberOfPages = 3;
[_scrollView setContentSize:CGSizeMake(_scrollView.frame.size.width * _pageControl.numberOfPages, _scrollView.frame.size.height)];
_scrollView.delegate = self;
[self createPageWithImage:_image1 forPage:0];
[self createPageWithImage:_image2 forPage:1];
[self createPageWithImage:_image3 forPage:2];
}
- (void)createPageWithImage:(UIImageView *)frameImage forPage:(int)page
{
UIView *newView = [[UIView alloc] initWithFrame: CGRectMake(_scrollView.frame.size.width * page, 0, _scrollView.frame.size.width, _scrollView.frame.size.height)];
[newView addSubview: frameImage];
[_scrollView addSubview: newView];
}
- (void)scrollViewDidScroll: (UIScrollView *) sView
{
CGFloat offset = _scrollView.contentOffset.x;
CGFloat pageSize = _scrollView.frame.size.width;
int page = floor((offset + (pageSize/2)) / pageSize);
_pageControl.currentPage = page;
}
- (IBAction)changeThePage
{
CGRect pageRect = CGRectMake(_pageControl.currentPage * _scrollView.frame.size.width, 0, _scrollView.frame.size.width, _scrollView.frame.size.height);
[_scrollView scrollRectToVisible: pageRect animated: YES];
}
Adding the methods which I have changed. I have commented wherever necessary.
- (void)setupScrollView {
_pageControl.currentPage = 0;
_pageControl.numberOfPages = 3 ;
//Add 2 more pages.
[_scrollView setContentSize:CGSizeMake(_scrollView.frame.size.width * (_pageControl.numberOfPages + 2), _scrollView.frame.size.height)];
_scrollView.delegate = self;
// Seriously recommend this for this type of apps.
_scrollView.pagingEnabled = YES;
// Do not instantiate imageviews. Send only image names as string.
// Add last image at beginning of scroll view.
[self createPageWithImageName:#"imageName3" forPage:0];
// Increase page number of existing images.
[self createPageWithImageName:#"imageName1" forPage:1];
[self createPageWithImageName:#"imageName2" forPage:2];
[self createPageWithImageName:#"imageName3" forPage:3];
//Add first image at end of scroll view
[self createPageWithImageName:#"imageName1" forPage:4];
// Show first image but present in second page.
[_scrollView setContentOffset:CGPointMake(_scrollView.frame.size.width, 0) animated:NO];
}
// Instead of sending image views, send image name. Create image view inside this method.
// This is because, since we are adding two more images, separate image view needs
// to be created. Otherwise, same image view will be used and one added at the end
// will be used as the frame of the image.
- (void)createPageWithImageName:(NSString *)imageName forPage:(int)page
{
UIView *newView = [[UIView alloc] initWithFrame: CGRectMake(_scrollView.frame.size.width * page, 0, _scrollView.frame.size.width, _scrollView.frame.size.height)];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:newView.bounds];
imageView.image = [UIImage imageNamed:imageName];
[newView addSubview: imageView];
[_scrollView addSubview: newView];
}
- (void)scrollViewDidScroll: (UIScrollView *) sView
{
CGFloat offset = _scrollView.contentOffset.x;
CGFloat pageSize = _scrollView.frame.size.width;
int page = floor((offset + (pageSize/2)) / pageSize);
if (page == 0) {
page = _pageControl.numberOfPages - 1;
}
else if (page == _pageControl.numberOfPages + 1) {
page = 0;
}
else {
page = page - 1;
}
_pageControl.currentPage = page;
// If present in scroll view's first page, move it to second last page
if (offset < pageSize) {
[_scrollView setContentOffset:CGPointMake(pageSize * 3 + offset, 0) animated:NO];
}
// If present in scroll view's last page, move it to second page.
else if (offset >= pageSize * (_pageControl.numberOfPages + 1)) {
CGFloat difference = offset - pageSize * _pageControl.numberOfPages;
[_scrollView setContentOffset:CGPointMake(difference, 0) animated:NO];
}
}
The method of changeThePage is not needed for this code.
Hope this answer helps you.

Image Split on Landscape/Portrait

I have Array of images, which I need to display on the Landscapeand portrait mode.. what I have done is that I have created a Array of images and displaying on the scrollView to see one at a time ..but problem is that When I move to Landscape to portrait or vice versa images get split ...view comes with the half previous image and half next.. this does not happen everytime...I dont know why the images are splitting and not exactly in half ...sometime split in different size..
#define portrait_width1 600.0
#define portrait_height1 600.0
#define landscape_width1 800.0
#define landscape_height1 445.0
CGFloat kScrollObjHeight_por1 = portrait_height1;
CGFloat kScrollObjWidth_por1 = portrait_width1;
- (void)viewDidLoad{
scrollView1.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView1.clipsToBounds = YES;
// default is NO, we want to restrict drawing within our scrollview
scrollView1.scrollEnabled = YES;
scrollView1.delegate = self;
scrollView1.pagingEnabled = YES;
[scrollView1 setShowsHorizontalScrollIndicator:NO];
[scrollView1 setShowsVerticalScrollIndicator:NO];
kNumImages=content.count;
for (i = 1; i <= content.count; i++)
{
NSArray *photos = [NSArray arrayWithObjects:
[UIImage imageNamed:#"c.jpg"],
[UIImage imageNamed:#"photo2m.jpg"],[UIImage imageNamed:#"photo1m.jpg"],[UIImage imageNamed:#"photo4m.jpg"],[UIImage imageNamed:#"photo2l.jpg"],[UIImage imageNamed:#"photo4l.jpg"],
nil] ;
UIImage *image = [photos objectAtIndex:i];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight_por1;
rect.size.width = kScrollObjWidth_por1;
rect.origin.y=scrollView1.frame.origin.y;
imageView.frame = rect;
imageView.tag = i;
[scrollArray addObject:imageView];
[scrollView1 addSubview:imageView];
[imageNameArray addObject:[[content objectAtIndex:i-1] _image_url]];
}
[self layoutScrollImages];
}
}
-(void)layoutScrollImages
{
#try {
UIImageView *view = nil;
NSArray *subviews = [scrollView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
CGRect frame;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth_por1);
}
}
// set the content size so it can be scrollable
[scrollView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth_por1), kScrollObjHeight_por1)];
// scrollView.contentSize = CGSizeMake(scrollView.contentSize.width,scrollView.frame.size.height);
NSLog(#"%d",[imageNameArray indexOfObject:Images]);
currentImage=[scrollArray objectAtIndex:[imageNameArray indexOfObject:Images]];
[scrollView1 scrollRectToVisible:currentImage.frame animated:YES];
}
#catch (NSException *exception) {
NSLog(#"ImageFullScreenViewController - layoutScrollImages Exception Name = %# Exception Reason = %#",[exception name],[exception reason]);
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
#try {
if ([UIDevice currentDevice].orientation== UIInterfaceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIInterfaceOrientationLandscapeRight)
{
if (!landscapeImgSCRf) {
CGFloat curXLoc = 0;
CGRect frame;
for (UIView *subview in scrollView1.subviews)
{
if ([subview isKindOfClass:[UIImageView class]])
{
if (!rightside2f) {
kScrollObjWidth_por1 = landscape_width1;
kScrollObjHeight_por1= landscape_height1;
curXLoc = subview.frame.origin.x;
rightside2f=YES;
}
frame.origin = CGPointMake(curXLoc, 0);
[subview setFrame: CGRectMake(curXLoc, subview.frame.origin.y, kScrollObjWidth_por1, kScrollObjHeight_por1)];
curXLoc += (kScrollObjWidth_por1);
scrollView1.frame=CGRectMake(scrollView1.frame.origin.x, scrollView1.frame.origin.y, scrollView1.frame.size.width, scrollView1.frame.size.height);
}
}
[scrollView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth_por1), kScrollObjHeight_por1)];
landscapeImgSCRf=YES;
}
}else
{
if (landscapeImgSCRf) {
CGFloat curXLoc = 0;
CGRect frame;
for (UIView *subview in scrollView1.subviews)
{
if ([subview isKindOfClass:[UIImageView class]])
{
if (rightside2f) {
kScrollObjWidth_por1 = portrait_width1;
kScrollObjHeight_por1= portrait_height1;
curXLoc = subview.frame.origin.x;
rightside2f=NO;
}
frame.origin = CGPointMake(curXLoc, 0);
[subview setFrame: CGRectMake(curXLoc, subview.frame.origin.y, kScrollObjWidth_por1, kScrollObjHeight_por1)];
curXLoc += (kScrollObjWidth_por1);
scrollView1.frame=CGRectMake(scrollView1.frame.origin.x, scrollView1.frame.origin.y, scrollView1.frame.size.width, scrollView1.frame.size.height);
}
}
landscapeImgSCRf=NO;
[scrollView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth_por1), kScrollObjHeight_por1)];
}
}
}
#catch (NSException *exception) {
NSLog(#"ImageFullScreenViewController - willRotateToInterfaceOrientation Exception Name = %# Exception Reason = %#",[exception name],[exception reason]);
}
}
check for image

Resources