Creating new instance of existing page to add to UIScrollView (paging) - objective-c

In part of my app, a button click creates a new page. However, I want that page to be exactly the same as the one I was on previously, but just a new instance of it. After asking the best way to do this on SO, I learned the UIScrollView with paging enabled was the best approach. So, I wrote some code to try to do what I was trying. However, when I press the button, the app just crashes. I'm assuming it got into some kind of recursion (calling itself again and again). Any insight into what might be wrong would be great. I can confirm that all the outlets are hooked up to their respective positions in StoryBoard.
-(IBAction)createContainer:(id)sender {
[allScrollViews addObject:self.containerView];
for (int i = 0; i < allScrollViews.count; i++) {
CGRect frame;
frame.origin.x = self.containerView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.containerView.frame.size;
UIView *subview = self.view;
subview.backgroundColor = self.view.backgroundColor;
[self.containerView addSubview:subview];
}
self.containerView.contentSize = CGSizeMake(self.containerView.frame.size.width * allScrollViews.count, self.containerView.frame.size.height);
}
Once again, pressing the button has to pretty much duplicate the view that I'm on (ViewController.m), and just make a new instance of it on a new page. My code is hopefully close to what I am trying to accomplish.
Thanks much!
~Carpetfizz
EDIT: If it helps, this gets highlighted when the app crashes:
0x2281b61: calll 0x2281b66 CA::Layer::ensure_transaction_recursively(CA::Transaction*) + 14

I think you should make like this:
-(IBAction)createContainer:(id)sender {
[allScrollViews addObject:self.containerView];
for (int i = 0; i < allScrollViews.count; i++) {
CGRect frame = self.containerView.frame;
frame.origin.x = self.containerView.frame.size.width * i;
frame.origin.y = 0;
self.containerView.frame = frame;
[self.scrollView addSubview: self.containerView];
}
self.scrollView.contentSize = CGSizeMake(self.containerView.frame.size.width * allScrollViews.count, self.containerView.frame.size.height);
}

Related

Unable to click the dots in Page Control

Unable to click the dots in Page Control. Also, need to change the UICollectionView while clicking the dots. Anyone help me regarding this?
-(void)changepage:(UIPageControl *)sender {
// UIPageControl *pager=sender;
page = sender.currentPage;
CGRect frame = self.AchievementCollection.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[self.AchievementCollection scrollRectToVisible:frame animated:YES];
NSLog(#"page control value %li",(long)sender.currentPage);
}
in Cell For Item at Index Path
AchievementCollectionCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"AchievementCollecti‌on" forIndexPath:indexPath];
[pageControls addTarget:self action:#selector(changepage:) forControlEvents:UIControlEventValueChanged];
cell.MiddleLabel.text = [[items objectAtIndex: indexPath.row]valueForKey:#"userCertificateName"];
cell.BottomLabel.text = [[items objectAtIndex: indexPath.row]valueForKey:#"userCertificateDesc"];
return cell;
}
I don't think you're supposed to let the dot clickable, since it's too small for a finger gesture. If you would like something like next / back, then you better have other 2 buttons to handle that.
But, IMHO, the best UX is still let user scroll the scrollview manually.

Navigating to a next page in a gridView

I need help developing a logic that navigates to the next page of a gridView. My current approach takes me to page 2 but does not advances any further than that.
Here is what I have tried so far.
NSInteger nextPage;
NSINteger currentPage;
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null]) {
CGFloat width = frame.size.width;
currentPage= floor((gridView.contentOffset.x+width/2)/width);
nextPage = currentPage+1; // update the next page button;
}
Next page button
- (IBAction)nextPage:(id)sender {
CGRect frame = gridView.frame;
frame.origin.x = frame.size.width * nextPage;
frame.origin.y = 0;
[gridView scrollRectToVisible:frame animated:YES];
}
Thanks.
The solution turned out to be very simple. I added a global variable to track the number of times the nextPage button was clicked and replaced the
NSInteger nextPage; with
int clickedNumber =0;
- (IBAction)nextPage:(id)sender {
clickedNumber = clickedNumber+1;
CGRect frame = gridView.frame;
frame.origin.x = frame.size.width * clickedNumber;
frame.origin.y = 0;
[gridView scrollRectToVisible:frame animated:YES];
NSLog(#"%d",clickedNumber);
}
This way every time the button is clicked the number is increased and it goes to goes to the next page according the number of times the button is clicked.
It and works like a charm. :)

Best way to animate visiblity of UICollectionViewCell in iOS7+

I need to animate the visibility of UICollectionViewCells on startup such that they are visible randomly when my application launches. But since I already have the items to be displayed they are visible at the same time. I tried below solution & it works correctly. But I want to know the best & optimized way to achieve this task
- (void)animateCollectionViewCellsVisiblity
{
// First set alpha to 0
for (NSUInteger i = 0; i< self.dataArray.count; i++)
{
[self applyAlpha:0.0 toItem:i inSection:0];
}
// Initially collectionview is hidden while fetching data, so show it now
self.collectionView.hidden = NO;
// Now set alpha to 1 with a random delay
for (NSUInteger i = 0; i< self.dataArray.count; i++)
{
CGFloat delay = [self randomNumberWithlowerBound:0 upperBound:self.dataArray.count] + 0.05;
[UIView animateWithDuration:.2 delay:delay options:UIViewAnimationOptionCurveEaseIn animations:^{
[self applyAlpha:1.0 toItem:i inSection:0];
} completion:nil];
}
}
- (void)applyAlpha:(CGFloat)alpha toItem:(NSInteger)item inSection:(NSInteger)section
{
MyCollectionViewCell *cell = (MyCollectionViewCell *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:item inSection:section]];
cell.alpha = alpha;
}
- (int)randomNumberWithlowerBound:(int)lowerBound upperBound:(int)upperBound
{
int randomValue = arc4random_uniform(upperBound - lowerBound + 1) + lowerBound;
return randomValue;
}
Your solution is great. That's how it is done. Looks pretty optimized to me.
You could make your code shorter by dropping the section parameter which is always zero. And you possibly eliminate the applyAlpha method by adding just two lines before your animate block.

how to develop two(or multi) screens with UITableView and switch between them using swipe and UISegmentedControl

Here is my screen
i am newbie for iOS development and wondered a lot for this task. i would like to ask in my work project there is UISegmentcontrol there is 6 segments and i had make them as scrollable and one single table view is there for every segment tap index pass to the tabl view's row and relod the table.i want to do like user can swipe on table view and along with segments change.
simply want to swipe to change table view and along with segment change.and individually segments are also scrollable itself which are already done.
e.g same as iOS notification centre.
Thanks in advance....Please help me for this task.
here is some code of segment control which i had developed for scrolling segments
-(void)viewDidLoad
{
UIScrollView * scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 76, 355, 29)];
self.segmentedControl.frame = CGRectMake(-18, 0, 820, 29);
scrollView.contentSize = CGSizeMake(self.segmentedControl.frame.size.width, self.segmentedControl.frame.size.height -1);
scrollView.showsHorizontalScrollIndicator = NO;
self.segmentedControl.selectedSegmentIndex = 0;
}
-(void)fillJournals
{
[journals removeAllObjects];
NSString *segmentName = [self.segmentedControl titleForSegmentAtIndex:self.segmentedControl.selectedSegmentIndex];
for (int i=0; i<30; i++)
{
[journals addObject:[NSString stringWithFormat:#"%# %d",segmentName,i+1]];
}
}
-(IBAction)categoryDidChange:(id)sender
{
[self fillJournals];
[self.payTable reloadData];
}
Use ContainerViewController and add Gesture to TableView.on swipe just change viewcontroller
let me know if it is useful for you..
Solution 2:
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
}
by using page you can reload table with respective array

Why is my UIButton still calling a method after I've button.enabled = NO;?

I've just started programming and I've got this far but I've been struggling with this now for a while and am completely stuck. I've created a 10x10 board of playing cards, from two decks. I've then made them all buttons in -(void)displayBoard below. Each card has a BOOL property card.button holding whether it should be enabled as a button or not.
I'm switching them on OK and all works fine. They start off untouchable, then I switch them on and they correctly call (void)boardCardPressed. However, when I switch them off there they graphically appear to be off, but are still calling (void)boardCardPressed when I touch them. If I log the button property, that is being set correctly. I suspect it's something to do with me adding the target and not removing, but everything i try makes no difference.
I've not found any help on this anywhere so any ideas, tips or help would be very much appreciated. BTW - I suspect my attempts aren't the most elegant, so tips there would be great too. It was the only way I could find to get my card images to be selectable :)
-(void)displayBoard{
board = [model board];
for (int x = 0; x < 10; x++){
for(int y = 0; y < 10; y++){
Card *tCard = [board getCardxpos:x ypos:y];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag = tCard.tag;
button.enabled = tCard.button;
button.adjustsImageWhenDisabled = NO;
[button setImage:tCard.image forState:UIControlStateNormal];
button.frame = CGRectMake(tCard.xPos, tCard.yPos, tCard.sizeW, tCard.sizeH);
[button setImage:tCard.image forState:UIControlEventTouchUpInside];
[button addTarget:self action:#selector(boardCardPressed:) forControlEvents:UIControlEventTouchUpInside];
[(SequenceView *)self.view drawIt:button];
}
}
}
-(void)boardCardPressed:(id)sender {
int tid = ((UIControl*)sender).tag;
int x = tid / 10;
int y = tid%10;
Card *tCard = [[model board] getCardxpos:x ypos:y];
tCard.chosen = YES;
tCard.button = NO;
[self displayBoard];
}
There is something that is not entirely clear to me in your code. As far as I see, you create the displayBoard and includes 100 buttons in it; when any of those buttons is touched, the boardCardPressed is called again and you create again the board, with its 100 buttons that have nothing to do with the original ones.
Is this meant to be so? Or could this have to do with the behavior you don't understand?