Obj-C- Update UICollectionView data without reloading entire collectionView? - ios

I have a UICollectionView where when cells are selected, they change to a color selected by the user. To paint the full picture: The color is selected by the user from a color wheel (UIImageView) with a tap gesture attached to it.
That said, when the user taps a new color, say purple (and resets the defined rString, bString & gString...) after selecting 3 cells and making them green, I want to reload the color they're using without wiping the initial 3 selected green cells from the Collection View. How can I accomplish this?
See code below.
ViewController.m
#interface ViewController () {
CGPoint lastPoint;
NSInteger rString;
NSInteger bString;
NSInteger gString;
UIColor *colour;
}
#property (strong, nonatomic, nullable) NSIndexPath *trackingCellIndexPath;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.ringCollectionView.allowsMultipleSelection = YES;
UITapGestureRecognizer * tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(tapGesture:)];
[self.colorWheel addGestureRecognizer:tapRecognizer];
self.colorWheel.userInteractionEnabled = YES;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"RingCollectionViewCell" forIndexPath:indexPath];
if (!cell.selectedBackgroundView) {
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
cell.selectedBackgroundView.backgroundColor = [UIColor grayColor];
} else {
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
cell.selectedBackgroundView.backgroundColor = [UIColor colorWithRed:rString/255.0 green:gString/255.0 blue:bString/255.0 alpha:1.0];
}
if ((indexPath.row >=9 && indexPath.row <=14) || ((indexPath.row >=17 && indexPath.row < 23) || (indexPath.row >=25 && indexPath.row <=30) || (indexPath.row >=33 && indexPath.row <=38))) {
NSLog(#"NOT AVAILABLE SORRY");
cell.backgroundColor = [UIColor whiteColor];
[cell setUserInteractionEnabled:NO];
}
return cell;
}
-(void)tapGesture:(UITapGestureRecognizer *)recognizer {
CGPoint location = [recognizer locationInView:recognizer.view];
CGPoint p = { round(location.x), round(location.y) };
_colorView.backgroundColor = [self colorInViewAtPoint:p];
UIColor *mylovelycolor = [self colorInViewAtPoint:p];
const CGFloat *components = CGColorGetComponents(mylovelycolor.CGColor);
NSLog(#"Red: %f", components[0]);
NSLog(#"Green: %f", components[1]);
NSLog(#"Blue: %f", components[2]);
NSLog(#"Alpha: %f", CGColorGetAlpha(mylovelycolor.CGColor));
int red = components[0] * 255;
int green = components[1] * 255;
int blue = components[2] * 255;
NSString *red1 = [#(red) stringValue];
NSString *green1 = [#(green) stringValue];
NSString *blue1 = [#(blue) stringValue];
NSInteger redInt = [red1 integerValue];
NSInteger greenInt = [green1 integerValue];
NSInteger blueInt = [blue1 integerValue];
rString = [red1 integerValue];
bString = [blue1 integerValue];
gString = [green1 integerValue];
self.redValue.text = red1;
self.greenValue.text = green1;
self.blueValue.text = blue1;
NSMutableString *str1 = [NSMutableString string];
for(NSInteger numberCopy = redInt; numberCopy > 0; numberCopy >>= 1)
{
[str1 insertString:((numberCopy & 1) ? #"1" : #"0") atIndex:0];
}
NSMutableString *str2 = [NSMutableString string];
for(NSInteger numberCopy = greenInt; numberCopy > 0; numberCopy >>= 1)
{
[str2 insertString:((numberCopy & 1) ? #"1" : #"0") atIndex:0];
}
NSMutableString *str3 = [NSMutableString string];
for(NSInteger numberCopy = blueInt; numberCopy > 0; numberCopy >>= 1)
{
[str3 insertString:((numberCopy & 1) ? #"1" : #"0") atIndex:0];
}
self.binaryString = [NSString stringWithFormat:#" %# %# %#", str1, str2, str3];
}

You need to track your user-selected colors in your data model.
In cellForItemAtIndexPath you want to set the cell's background color (or whatever element you're using) to the data element color.
When the user has one or more cells selected, and taps your "colorWheel," update your data model and then either set the cell elements directly or reload those cells.
Here is a very simple example...
MyDataObject.h
//
// MyDataObject.h
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
#interface MyDataObject : NSObject
#property (strong, nonatomic) UIColor *userColor;
#end
NS_ASSUME_NONNULL_END
MyDataObject.m
//
// MyDataObject.m
//
#import "MyDataObject.h"
#implementation MyDataObject
#end
MyCollectionViewCell.h
//
// MyCollectionViewCell.h
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
#interface MyCollectionViewCell : UICollectionViewCell
#property (strong, nonatomic) UILabel *label;
#end
NS_ASSUME_NONNULL_END
MyCollectionViewCell.m
//
// MyCollectionViewCell.m
//
#import "MyCollectionViewCell.h"
#implementation MyCollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self commonInit];
}
return self;
}
- (void)commonInit {
_label = [UILabel new];
_label.textAlignment = NSTextAlignmentCenter;
_label.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
_label.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:_label];
UILayoutGuide *g = [self.contentView layoutMarginsGuide];
[NSLayoutConstraint activateConstraints:#[
[_label.widthAnchor constraintEqualToAnchor:g.widthAnchor multiplier:0.8],
[_label.heightAnchor constraintEqualToAnchor:g.heightAnchor multiplier:0.8],
[_label.centerXAnchor constraintEqualToAnchor:g.centerXAnchor],
[_label.centerYAnchor constraintEqualToAnchor:g.centerYAnchor],
]];
self.contentView.layer.borderColor = [UIColor yellowColor].CGColor;
}
- (void)setSelected:(BOOL)selected {
[super setSelected:selected];
self.contentView.layer.borderWidth = selected ? 2 : 0;
}
#end
MyTestViewController.h
//
// MyTestViewController.h
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
#interface MyTestViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegate>
#end
NS_ASSUME_NONNULL_END
MyTestViewController.m
//
// MyTestViewController.m
//
#import "MyTestViewController.h"
#import "MyCollectionViewCell.h"
#import "MyDataObject.h"
#interface MyTestViewController ()
{
NSMutableArray <MyDataObject *>*myCellData;
UICollectionView *collectionView;
}
#end
#implementation MyTestViewController
- (void)viewDidLoad {
[super viewDidLoad];
UICollectionViewFlowLayout *fl = [UICollectionViewFlowLayout new];
fl.itemSize = CGSizeMake(50, 50);
fl.scrollDirection = UICollectionViewScrollDirectionHorizontal;
collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:fl];
collectionView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:collectionView];
UILayoutGuide *g = [self.view safeAreaLayoutGuide];
[NSLayoutConstraint activateConstraints:#[
[collectionView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:20.0],
[collectionView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-20.0],
[collectionView.heightAnchor constraintEqualToConstant:240.0],
[collectionView.centerYAnchor constraintEqualToAnchor:g.centerYAnchor],
]];
// a few color views to tap, and an
// "Instructions" label
UILabel *label = [UILabel new];
label.text = #"Tap a color to change the selected cells:";
UIStackView *stack = [UIStackView new];
NSArray *colors = #[
[UIColor redColor],
[UIColor greenColor],
[UIColor blueColor],
[UIColor systemYellowColor],
[UIColor systemTealColor],
];
for (UIColor *c in colors) {
UIView *v = [UIView new];
v.backgroundColor = c;
UITapGestureRecognizer *t = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(gotTap:)];
[v addGestureRecognizer:t];
[stack addArrangedSubview:v];
}
stack.spacing = 20.0;
stack.distribution = UIStackViewDistributionFillEqually;
label.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:label];
stack.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:stack];
[NSLayoutConstraint activateConstraints:#[
[stack.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:20.0],
[stack.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-20.0],
[stack.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-20.0],
[stack.heightAnchor constraintEqualToConstant:40.0],
[label.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:20.0],
[label.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-20.0],
[label.bottomAnchor constraintEqualToAnchor:stack.topAnchor constant:-4.0],
]];
collectionView.dataSource = self;
collectionView.delegate = self;
collectionView.allowsMultipleSelection = YES;
[collectionView registerClass:MyCollectionViewCell.class forCellWithReuseIdentifier:#"c"];
// create 50 objects for our data
myCellData = [NSMutableArray new];
for (int i = 0; i < 50; i++) {
MyDataObject *obj = [MyDataObject new];
obj.userColor = [UIColor redColor];
[myCellData addObject:obj];
}
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return myCellData.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// dequeue a cell
MyCollectionViewCell *c = (MyCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"c" forIndexPath:indexPath];
// get the data object
MyDataObject *obj = (MyDataObject *)[myCellData objectAtIndex:indexPath.item];
// set cell's contentView.backgroundColor to the data object's .userColor
c.contentView.backgroundColor = obj.userColor;
// set the cell's label text
c.label.text = [NSString stringWithFormat:#"%ld", indexPath.item];
return c;
}
- (void)gotTap:(UITapGestureRecognizer *)g {
if (collectionView.indexPathsForSelectedItems.count == 0) {
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:#"Error"
message:#"No cells are selected!"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okButton = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
}];
[alert addAction:okButton];
[self presentViewController:alert animated:YES completion:nil];
return;
}
UIView *v = g.view;
if (v) {
// get the background color from the tapped view
UIColor *color = v.backgroundColor;
// loop through selected cells
for (NSIndexPath *p in collectionView.indexPathsForSelectedItems) {
// update the object in our data
[myCellData objectAtIndex:p.item].userColor = color;
// get a reference to the cell
MyCollectionViewCell *c = (MyCollectionViewCell *)[collectionView cellForItemAtIndexPath:p];
// set its background color
c.contentView.backgroundColor = color;
// if we want to auto-deselect the cells
[collectionView deselectItemAtIndexPath:p animated:YES];
}
}
}
#end
So,
our data object has just a single property: userColor
our cell class has a centered label
our controller
creates a horizontal scrolling collection view
creates an array of 50 data objects, with default userColor of red
adds 5 color views to select from
When a cell is selected, it will be outlined in yellow. When a color view is tapped, we:
update the data model for the currently selected cells
set the background color of the contentView of the currently selected cells
deselect the currently selected cells
It looks like this:
then we select cells 5, 9, 14:
tap on the Green view:
then we select cells 16, 17, 18:
tap on the Blue view:
then we scroll a little and select cells 17, 21, 24, 25, 26:
tap on the Yellow view:
and so on.

Related

When did UITableViewCell done layout subview?

As shown in the following image, I want to add a tip(subview of the biggest UIView) that left align with the UIStackView in UITableViewCell. The width of UIStackView in UITableViewCell is dynamic, so I need to place the tip view after the UITableViewCell layout its subviews.
I've tried to add the tip view in willDisplayCell function, but the position I get there is not the final position.
Also, I tried to set the tip view's position in the UITableViewCell's layoutSubviews function. Since this function is called multiple times, the tip will go to the expected place eventually, but it will flicker at the beginning.
So in which function should I add the tip view?
--------Edited--------
Add a code snippet to make it clearer. I just want to know where should I put the following code, so that rect.origin.x is the final position of the stackview.
UIView *view = self.view;
CGRect rect = [cell.stackView convertRect:cell.stackView.bounds toView:view];
[self.tipView.leadingAnchor constraintEqualToAnchor:view.leadingAnchor constant:rect.origin.x].active = YES;
[self.tipView.trailingAnchor constraintLessThanOrEqualToAnchor:view.trailingAnchor constant:-marginConstant].active = YES;
[self.tipView.bottomAnchor constraintEqualToAnchor:self.tableView.bottomAnchor constant:-TSkBubbleClickAreaHeight-marginConstant].active = YES;
[view layoutIfNeeded];
Edit
To try and directly answer your question, you know when the layout of the content of the cell is completely finished when whatever you're doing to the cell is done. So, to know exactly when your cell's Stack View has been laid-out, you could subclass the stack view and implement layoutSubviews in that subclass.
Since it's still not clear exactly what you're doing, I'll offer a couple approaches...
If you are calling reloadData on the table view, you could try this:
[tableView reloadData];
dispatch_async(dispatch_get_main_queue(), ^{
[self showTipView:pth];
});
If you are calling insertRowsAtIndexPaths, you could try this:
[CATransaction begin];
[CATransaction setCompletionBlock:^{
[self showTipView:pth];
}];
[self->tableView insertRowsAtIndexPaths:#[pth] withRowAnimation:UITableViewRowAnimationRight];
[CATransaction commit];
Here's an example (I've tried to keep it simple, and provide clear comments):
ExampleTableViewCell.h
//
// ExampleTableViewCell.h
// Created by Don Mag on 9/15/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
#interface ExampleTableViewCell : UITableViewCell
- (void) configureCell:(NSString *)s;
- (UIStackView *)getStackRef;
#end
NS_ASSUME_NONNULL_END
ExampleTableViewCell.m
//
// ExampleTableViewCell.m
// Created by Don Mag on 9/15/20.
//
#import "ExampleTableViewCell.h"
#interface ExampleTableViewCell ()
{
UIStackView *stackView;
UILabel *label;
}
#end
#implementation ExampleTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self commonInit];
}
return self;
}
- (void) commonInit {
label = [UILabel new];
label.backgroundColor = [UIColor yellowColor];
stackView = [UIStackView new];
stackView.translatesAutoresizingMaskIntoConstraints = NO;
[stackView addArrangedSubview:label];
[self.contentView addSubview:stackView];
UILayoutGuide *g = self.contentView.layoutMarginsGuide;
[NSLayoutConstraint activateConstraints:#[
// constrain stack view Top: 0 / Trailing: 0 / Bottom: 0
[stackView.topAnchor constraintEqualToAnchor:g.topAnchor constant:0.0],
[stackView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:0.0],
[stackView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:0.0],
]];
}
- (void) configureCell:(NSString *)s {
label.text = s;
}
- (UIStackView *)getStackRef {
return stackView;
}
#end
ExampleViewController.h
//
// ExampleViewController.h
// Created by Don Mag on 9/15/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
#interface ExampleViewController : UIViewController
#end
NS_ASSUME_NONNULL_END
ExampleViewController.m
//
// ExampleViewController.m
// Created by Don Mag on 9/15/20.
//
#import "ExampleViewController.h"
#import "ExampleTableViewCell.h"
#interface ExampleViewController () <UITableViewDataSource, UITableViewDelegate, UIScrollViewDelegate>
{
NSMutableArray *myData;
NSMutableArray *sampleStrings;
UIView *tipView;
UIButton *reloadButton;
UIButton *insertButton;
UITableView *tableView;
NSInteger idx;
NSInteger insertRow;
}
#end
#implementation ExampleViewController
- (void)viewDidLoad {
[super viewDidLoad];
// row number to insert and show the tipView
insertRow = 7;
// init some sample data
myData = [NSMutableArray new];
for (int i = 0; i < 30; i++) {
NSString *s = [NSString stringWithFormat:#"Row %i", i];
[myData addObject:s];
}
// a few example strings
sampleStrings = [NSMutableArray new];
[sampleStrings addObject:#"Short text example."];
[sampleStrings addObject:#"A little more text example."];
[sampleStrings addObject:#"Considerably longer text for this example."];
// index for sampleStrings array
idx = -1;
// create a "tip view"
// red background view with
// green background label
// label is inset 4-pts on each side
tipView = [UIView new];
tipView.backgroundColor = [UIColor redColor];
UILabel *tipLabel = [UILabel new];
tipLabel.backgroundColor = [UIColor greenColor];
tipLabel.text = #"This is the tip!";
tipView.translatesAutoresizingMaskIntoConstraints = NO;
tipLabel.translatesAutoresizingMaskIntoConstraints = NO;
[tipView addSubview:tipLabel];
[NSLayoutConstraint activateConstraints:#[
[tipLabel.topAnchor constraintEqualToAnchor:tipView.topAnchor constant:4.0],
[tipLabel.leadingAnchor constraintEqualToAnchor:tipView.leadingAnchor constant:4.0],
[tipLabel.bottomAnchor constraintEqualToAnchor:tipView.bottomAnchor constant:-4.0],
[tipLabel.trailingAnchor constraintEqualToAnchor:tipView.trailingAnchor constant:-4.0],
]];
// init buttons
reloadButton = [UIButton new];
[reloadButton setTitle:#"Reload" forState:UIControlStateNormal];
[reloadButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[reloadButton setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
[reloadButton setBackgroundColor:[UIColor blueColor]];
insertButton = [UIButton new];
[insertButton setTitle:#"Insert" forState:UIControlStateNormal];
[insertButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[insertButton setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
[insertButton setBackgroundColor:[UIColor blueColor]];
// init table view
tableView = [UITableView new];
for (UIView *v in #[reloadButton, insertButton, tableView]) {
v.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:v];
}
UILayoutGuide *g = self.view.safeAreaLayoutGuide;
[NSLayoutConstraint activateConstraints:#[
// buttons at top
[reloadButton.topAnchor constraintEqualToAnchor:g.topAnchor constant:20.0],
[reloadButton.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:24.0],
[insertButton.topAnchor constraintEqualToAnchor:g.topAnchor constant:20.0],
[insertButton.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-24.0],
[insertButton.leadingAnchor constraintEqualToAnchor:reloadButton.trailingAnchor constant:20.0],
[insertButton.widthAnchor constraintEqualToAnchor:reloadButton.widthAnchor],
// constrain tableView Top: 20-pts from buttons / Leading: 0 / Trailing: 0 / Bottom: 0
[tableView.topAnchor constraintEqualToAnchor:reloadButton.bottomAnchor constant:20.0],
[tableView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:0.0],
[tableView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:0.0],
[tableView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:0.0],
]];
[tableView registerClass:[ExampleTableViewCell class] forCellReuseIdentifier:#"exCell"];
tableView.delegate = self;
tableView.dataSource = self;
[reloadButton addTarget:self action:#selector(btnTap:) forControlEvents:UIControlEventTouchUpInside];
[insertButton addTarget:self action:#selector(btnTap:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
[tipView removeFromSuperview];
}
- (void)btnTap:(UIButton *)btn {
// remove tipView if it's showing
[tipView removeFromSuperview];
NSString *s = sampleStrings[++idx % 3];
if (btn == reloadButton) {
[self reloadMethod:s];
} else {
[self insertMethod:s];
}
}
- (void)insertMethod:(NSString *)s {
// IndexPath for cell you want
__block NSIndexPath *pth = [NSIndexPath indexPathForRow:insertRow inSection:0];
[myData insertObject:s atIndex:pth.row];
[CATransaction begin];
[CATransaction setCompletionBlock:^{
[self showTipView:pth];
}];
[self->tableView insertRowsAtIndexPaths:#[pth] withRowAnimation:UITableViewRowAnimationRight];
[CATransaction commit];
}
- (void)reloadMethod:(NSString *)s {
// IndexPath for cell you want
__block NSIndexPath *pth = [NSIndexPath indexPathForRow:insertRow inSection:0];
[myData insertObject:s atIndex:pth.row];
[tableView reloadData];
dispatch_async(dispatch_get_main_queue(), ^{
[self showTipView:pth];
});
}
- (void)showTipView:(NSIndexPath *)pth {
// get a reference to the cell
ExampleTableViewCell *cell = [tableView cellForRowAtIndexPath:pth];
// if row is not visible
if (!cell) {
return;
}
// get a reference to the cell's stack view
UIStackView *stack = [cell getStackRef];
// add tipView to self.view
[self.view addSubview:tipView];
// constrain tipView
// Leading to stack view's Leading
// Bottom to cell's Top - 4
[NSLayoutConstraint activateConstraints:#[
[tipView.leadingAnchor constraintEqualToAnchor:stack.leadingAnchor constant:0.0],
[tipView.bottomAnchor constraintEqualToAnchor:cell.topAnchor constant:-4.0],
]];
// if we want to "fade-in" the tipView
[tipView setAlpha:0.0];
[UIView animateWithDuration:0.3
animations:^{
[self->tipView setAlpha:1.0];
}];
}
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
ExampleTableViewCell *c = (ExampleTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"exCell" forIndexPath:indexPath];
[c configureCell:myData[indexPath.row]];
return c;
}
- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [myData count];
}
#end

Detect button click event on customcell

I have added a custom cell as follows for stepper progress. UI perspective, it looks what I want, but I could not able to figure out how I could able to determine whether or not button has been clicked.
I have inspired via https://github.com/yenbekbay/AYStepperView, but this one has PageViewController which I could not able to add it in the tableCell.
#import "StepperProgressTableViewCell.h"
#import "AYStepperView.h"
static CGFloat const kFormStepperViewHeight = 80;
#interface StepperProgressTableViewCell ()
#property (nonatomic) AYStepperView *stepperView;
#property (nonatomic) NSUInteger currentIndex;
#property (nonatomic) NSUInteger currentStep;
#end
#implementation StepperProgressTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
[self setUpViews];
self.currentIndex = 0;
self.currentStep = 0;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
}
#pragma mark Private
- (void)setUpViews {
self.stepperView = [[AYStepperView alloc]initWithFrame:CGRectMake(0, 40 , self.frame.size.width, kFormStepperViewHeight)
titles:#[NSLocalizedString(#"Start", nil),
NSLocalizedString(#"Cooking", nil),
NSLocalizedString(#"Ready", nil)]];
self.stepperView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
self.stepperView.userInteractionEnabled = YES;
[self addSubview:self.stepperView];
self.containerView = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.stepperView.frame), CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - CGRectGetMaxY(self.stepperView.frame))];
[self addSubview:self.containerView];
}
#end
AYStepperView.m
#import "AYStepperView.h"
#import <pop/POP.h>
static UIEdgeInsets const kStepperViewPadding = {
15, 0, 15, 0
};
static CGFloat const kStepperLabelsSpacing = 10;
static CGFloat const kStepperPipeHeight = 5;
#interface AYStepperView ()
#property (nonatomic) UIView *pipeView;
#property (nonatomic) UIView *labelsView;
#property (nonatomic) UIView *pipeBackgroundView;
#property (nonatomic) UIView *pipeFillView;
#property (nonatomic) NSMutableArray *stepLabels;
#end
#implementation AYStepperView
#pragma mark Initialization
- (instancetype)initWithFrame:(CGRect)frame titles:(NSArray *)titles {
self = [super initWithFrame:frame];
if (!self) {
return nil;
}
_titles = titles;
self.backgroundColor = [UIColor colorWithRed:0.98f green:0.98f blue:0.98f alpha:1];
self.tintColor = [UIColor colorWithRed:0.2f green:0.29f blue:0.37f alpha:1];
self.pipeView = [[UIView alloc] initWithFrame:CGRectMake(kStepperViewPadding.left, kStepperViewPadding.top, CGRectGetWidth(self.bounds) - kStepperViewPadding.left - kStepperViewPadding.right, CGRectGetHeight(self.bounds) / 2 - kStepperViewPadding.top)];
[self addSubview:self.pipeView];
self.labelsView = [[UIView alloc] initWithFrame:CGRectMake(kStepperViewPadding.left, CGRectGetMaxY(self.pipeView.frame) + kStepperViewPadding.top, CGRectGetWidth(self.bounds) - kStepperViewPadding.left - kStepperViewPadding.right, CGRectGetHeight(self.bounds) / 2 - kStepperViewPadding.top - kStepperViewPadding.bottom)];
[self addSubview:self.labelsView];
self.pipeBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, (CGRectGetHeight(self.pipeView.bounds) - kStepperPipeHeight) / 2, CGRectGetWidth(self.pipeView.bounds), kStepperPipeHeight)];
self.pipeBackgroundView.backgroundColor = [UIColor lightGrayColor];
[self.pipeView addSubview:self.pipeBackgroundView];
CGRect pipeFillViewFrame = self.pipeBackgroundView.frame;
pipeFillViewFrame.size.width = 0;
self.pipeFillView = [[UIView alloc] initWithFrame:pipeFillViewFrame];
self.pipeFillView.backgroundColor = self.tintColor;
[self.pipeView addSubview:self.pipeFillView];
_stepButtons = [NSMutableArray new];
_stepLabels = [NSMutableArray new];
for (NSUInteger i = 0; i < titles.count; i++) {
UIButton *stepButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, CGRectGetHeight(self.pipeView.bounds), CGRectGetHeight(self.pipeView.bounds))];
stepButton.center = CGPointMake(CGRectGetWidth(self.pipeView.bounds) * (i + 0.5f) / titles.count, stepButton.center.y);
stepButton.clipsToBounds = YES;
stepButton.tag = i;
stepButton.layer.cornerRadius = CGRectGetHeight(stepButton.bounds) / 2;
stepButton.backgroundColor = [UIColor lightGrayColor];
[self.pipeView addSubview:stepButton];
[self.stepButtons addObject:stepButton];
UILabel *stepLabel = [UILabel new];
stepLabel.font = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]];
stepLabel.textColor = self.tintColor;
stepLabel.textAlignment = NSTextAlignmentCenter;
stepLabel.text = titles[i];
stepLabel.numberOfLines = 0;
stepLabel.frame = (CGRect) {
stepLabel.frame.origin, [stepLabel sizeThatFits:CGSizeMake(CGRectGetWidth(self.pipeView.bounds) / titles.count - kStepperLabelsSpacing, 0)]
};
stepLabel.center = CGPointMake(CGRectGetWidth(self.labelsView.bounds) * (i + 0.5f) / titles.count, CGRectGetHeight(self.labelsView.bounds) / 2);
[self.labelsView addSubview:stepLabel];
[self.stepLabels addObject:stepLabel];
}
_currentStepIndex = 0;
[self completeStepAtIndex:0 until:1 completionBlock:nil];
return self;
}
#pragma mark Public
- (void)updateCurrentStepIndex:(NSUInteger)currentStepIndex completionBlock:(void (^)())completionBlock {
if (currentStepIndex >= self.titles.count || currentStepIndex == self.currentStepIndex) {
if (completionBlock) {
completionBlock();
}
} else {
NSUInteger previousStepIndex = self.currentStepIndex;
_currentStepIndex = currentStepIndex;
if ((NSInteger)currentStepIndex - (NSInteger)previousStepIndex > 0) {
[self completeStepAtIndex:previousStepIndex + 1 until:currentStepIndex + 1 completionBlock:completionBlock];
} else {
[self uncompleteStepAtIndex:previousStepIndex until:currentStepIndex - 1 completionBlock:completionBlock];
}
}
}
#pragma mark Setters
- (void)setTintColor:(UIColor *)tintColor {
_tintColor = tintColor;
self.pipeFillView.backgroundColor = tintColor;
for (UILabel *label in self.stepLabels) {
label.textColor = tintColor;
}
[self.stepButtons[self.currentStepIndex] setBackgroundColor:tintColor];
}
#pragma mark Private
- (void)completeStepAtIndex:(NSUInteger)index until:(NSUInteger)until completionBlock:(void (^)())completionBlock {
if (index == until) {
if (completionBlock) {
completionBlock();
}
} else {
[UIView animateWithDuration:0.2f animations:^{
CGRect pipeFillViewFrame = self.pipeFillView.frame;
NSLog(#"%lu, %lu",until, index);
if(index == _titles.count - 1)
{
pipeFillViewFrame.size.width = CGRectGetWidth(self.pipeBackgroundView.bounds) * (index + 1.0f) / self.titles.count;
}
else
{
pipeFillViewFrame.size.width = CGRectGetWidth(self.pipeBackgroundView.bounds) * (index + 0.5f) / self.titles.count;
}
self.pipeFillView.frame = pipeFillViewFrame;
} completion:^(BOOL finishedWidthAnimation) {
[self completeStepAtIndex:index + 1 until:until completionBlock:completionBlock];
UIView *stepButton = self.stepButtons[index];
stepButton.backgroundColor = self.tintColor;
POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.velocity = [NSValue valueWithCGSize:CGSizeMake(3.f, 3.f)];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
scaleAnimation.springBounciness = 5.f;
[stepButton.layer pop_addAnimation:scaleAnimation forKey:#"scaleAnimation"];
}];
}
}
- (void)uncompleteStepAtIndex:(NSUInteger)index until:(NSUInteger)until completionBlock:(void (^)())completionBlock {
if (index == until) {
if (completionBlock) {
completionBlock();
}
} else {
if (index > until + 1) {
UIView *stepButton = self.stepButtons[index];
stepButton.backgroundColor = [UIColor lightGrayColor];
POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.velocity = [NSValue valueWithCGSize:CGSizeMake(3.f, 3.f)];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
scaleAnimation.springBounciness = 5.f;
[stepButton.layer pop_addAnimation:scaleAnimation forKey:#"scaleAnimation"];
}
[UIView animateWithDuration:0.2f animations:^{
CGRect pipeFillViewFrame = self.pipeFillView.frame;
pipeFillViewFrame.size.width = CGRectGetWidth(self.pipeBackgroundView.bounds) * (index + 0.5f) / self.titles.count;
self.pipeFillView.frame = pipeFillViewFrame;
} completion:^(BOOL finishedWidthAnimation) {
[self uncompleteStepAtIndex:index - 1 until:until completionBlock:completionBlock];
}];
}
}
#end
If you want to catch events from a cell to the view controller, the simplest way is to create a protocol and set the view controller as the cell's delegate. I'm sure there are many similar questions here that can help you like this one for example.

Adding Subview to UICollectionViewCell Subclass?

I seem to be having trouble adding a subview to a view within my UICollectionViewCell subclass.
I have an abstract UICollectionViewCell subclass titled MessageItem, which looks like this:
I've created a few classes that inherit from this (since they all use the same logic for the header and footer). However I can't seem to add any subviews into MessageItem's blue view from within the child subclasses.
For example one of the child views is called TextItem. I'm trying to add a label to it's parent messageView (the blue view) but it only works if I do it in my UIViewController's cellForItemAtIndexPath:(NSIndexPath *)indexPath method, and not in my custom subclass.
This is how I'm trying to add it in my child subclass:
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
//Setup Message Label
[self setupMessageLabel];
}
return self;
}
#pragma mark - Setup Methods
- (void)setupMessageLabel {
NSLog(#"Setting up label");
//Setup Message Label
self.messageLabel = [TTTAttributedLabel new];
self.messageLabel.verticalAlignment = TTTAttributedLabelVerticalAlignmentCenter;
self.messageLabel.textInsets = UIEdgeInsetsMake(8, 8, 8, 8);
self.messageLabel.numberOfLines = 0;
[self.messageContentView addSubview:self.messageLabel];
[self.messageContentView autoPinEdgesToSuperviewEdges];
//Update Label Color
self.messageLabel.backgroundColor = FlatRed;
}
Note: I'm not using storyboard or xibs. Could that be the problem?
Update
This is what my MessageItem class is implemented:
MessageItem.h
#import <UIKit/UIKit.h>
#class Message;
#interface MessageItem : UICollectionViewCell
#property (nonatomic, strong) Message *message;
#property (nonatomic, strong) UIView *messageContentView;
#end
MessageItem.m
#interface MessageItem ()
#property (nonatomic, strong) TTTAttributedLabel *headerLabel;
#property (nonatomic, strong) TTTAttributedLabel *footerLabel;
#end
#implementation MessageItem
#synthesize message = _message;
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
//Setup Main View
[self setupMainView];
}
return self;
}
#pragma mark - Setup Methods
- (void)setupMainView {
//Setup Header
[self setupHeaderLabel];
//Setup Message
[self setupMessageView];
//Setup Footer View
[self setupFooterLabel];
}
- (void)setupHeaderLabel {
//Setup Header Label
self.headerLabel = [[TTTAttributedLabel alloc] initForAutoLayout];
self.headerLabel.font = [UIFont fontWithName:#"Lato-Bold" size:12.0];
self.headerLabel.textColor = FlatGray;
self.headerLabel.textAlignment = NSTextAlignmentCenter;
self.headerLabel.verticalAlignment = TTTAttributedLabelVerticalAlignmentCenter;
self.headerLabel.textInsets = UIEdgeInsetsMake(0, 8, 0, 8);
self.headerLabel.backgroundColor = FlatPurple;
[self.contentView addSubview:self.headerLabel];
[self.headerLabel autoSetDimension:ALDimensionHeight toSize:20.0];
[self.headerLabel autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero excludingEdge:ALEdgeBottom];
}
- (void)setupMessageView {
//Setup Message View
self.messageContentView = [UIView new];
self.messageContentView.backgroundColor = [UIColor blueColor];
[self.contentView addSubview:self.messageContentView];
[self.messageContentView autoSetDimension:ALDimensionHeight toSize:30 relation:NSLayoutRelationGreaterThanOrEqual];
[self.messageContentView autoPinEdgeToSuperviewEdge:ALEdgeLeading];
[self.messageContentView autoPinEdgeToSuperviewEdge:ALEdgeTrailing];
[self.messageContentView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.headerLabel];
}
- (void)setupFooterLabel {
//Setup Footer Label
self.footerLabel = [[TTTAttributedLabel alloc] initForAutoLayout];
self.footerLabel.font = [UIFont fontWithName:#"Lato-Bold" size:10.0];
self.footerLabel.textColor = FlatGray;
self.footerLabel.backgroundColor = FlatGreen;
self.footerLabel.textAlignment = NSTextAlignmentLeft;
self.footerLabel.textInsets = UIEdgeInsetsMake(0, 8, 0, 8);
[self.contentView addSubview:self.footerLabel];
[self.footerLabel autoSetDimension:ALDimensionHeight toSize:10.0];
[self.footerLabel autoPinEdgeToSuperviewEdge:ALEdgeLeading];
[self.footerLabel autoPinEdgeToSuperviewEdge:ALEdgeTrailing];
[self.footerLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[self.footerLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.messageContentView];
}
TextItem.m
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
//Setup Message Label
[self setupMessageLabel];
}
return self;
}
#pragma mark - Setup Methods
- (void)setupMessageLabel {
//Setup Message Label
self.messageLabel = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(0, 0, 320, 100)];
self.messageLabel.verticalAlignment = TTTAttributedLabelVerticalAlignmentCenter;
self.messageLabel.textInsets = UIEdgeInsetsMake(8, 8, 8, 8);
self.messageLabel.numberOfLines = 0;
[self.messageContentView addSubview:self.messageLabel];
//Update Label Color
self.messageLabel.backgroundColor = FlatRed;
}
#pragma mark - Setter Methods
- (void)setMessageText:(NSString *)text {
//Incoming Text Message
NSMutableAttributedString *textString = [[NSMutableAttributedString alloc] initWithString:text];
[textString addAttribute:NSForegroundColorAttributeName value:[UIColor darkGrayColor] range:NSMakeRange(0, textString.length)];
[textString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:16 weight:UIFontWeightLight] range:NSMakeRange(0, textString.length)];
//Set Paragraph Style
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.minimumLineHeight = 20;
paragraphStyle.maximumLineHeight = 20;
[textString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, textString.length)];
//Update Message Label
[self.messageLabel setText:textString];
NSLog(#"Set Message Label Text");
}
- (void)setMessage:(Message *)message {
//Super
[super setMessage:message];
//Update Message Text
[self setMessageText:message.text];
}
This is what my collectionView looks like:
I would at least expect the color of the messageLabel to reflect the change in TextItem, but it doesn't.
Have you implement initWithCoder?
- (id)initWithCoder:(NSCoder*)aDecoder
{
if(self = [super initWithCoder:aDecoder]) {
// Do something
}
return self;
}
I don't have all your code, but you code looks good to me. Maybe the problem was how you init the TextItem.
Here is a demo using your code, it works fine to me. https://www.dropbox.com/s/7qp9ayqnyacf57j/CustomCellView.zip?dl=0

How to autolayout this scroll view?

I am working with this app: http://www.raywenderlich.com/13541/how-to-create-an-app-like-instagram-with-a-web-service-backend-part-22 there is a screen called stream screen that lists jpegs in a UIScrollView named list view. The apps was made for iPhone originally so the author has the storyboards set up for iPhone. How can I resize the list view to fit both iPhones and iPads while scaling the contentt?
Additional info: the storyboard has one uiscrollview. Right now i have the size set to 1192 height 1080 width because I am testing on an iPad and this are the previous dimensions I've used successfully. However when the screen itself loads , it only takes up about a 3rd of the width of the total UIScrollView.
update
//photoscreen.h
//
#import <UIKit/UIKit.h>
//1 layout config
#define kThumbSide 90
#define kPadding 10
//2 define the thumb delegate protocol
#protocol PhotoViewDelegate <NSObject>
-(void)didSelectPhoto:(id)sender;
#end
//3 define the thumb view interface
#interface PhotoView : UIButton
{
}
#property (assign, nonatomic) id<PhotoViewDelegate> delegate;
-(id)initWithIndex:(int)i andData:(NSDictionary*)data;
#end
//this code is from photoview,which acts as a delegate for stream screen.m likewise, it formats the streams quality such as picture spacing
#import "PhotoView.h"
#import "API.h"
#implementation PhotoView
#synthesize delegate;
-(id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(id)initWithIndex:(int)i andData:(NSDictionary*)data {
self = [super init];
if (self !=nil) {
//initialize
self.tag = [[data objectForKey:#"IdPhoto"] intValue];
int row = i/3;
int col = i % 3;
self.frame = CGRectMake(1.5*kPadding+col*(kThumbSide+kPadding), 1.5*kPadding+row*(kThumbSide+kPadding), kThumbSide, kThumbSide);
self.backgroundColor = [UIColor grayColor];
//add the photo caption
UILabel* caption = [[UILabel alloc] initWithFrame:CGRectMake(0, kThumbSide-16, kThumbSide, 16)];
caption.backgroundColor = [UIColor blackColor];
caption.textColor = [UIColor whiteColor];
caption.textAlignment = UITextAlignmentCenter;
caption.font = [UIFont systemFontOfSize:12];
caption.text = [NSString stringWithFormat:#"#%#",[data objectForKey:#"username"]];
[self addSubview: caption];
//add touch event
[self addTarget:delegate action:#selector(didSelectPhoto:) forControlEvents:UIControlEventTouchUpInside];
//load the image
API* api = [API sharedInstance];
int IdPhoto = [[data objectForKey:#"IdPhoto"] intValue];
NSURL* imageURL = [api urlForImageWithId:[NSNumber numberWithInt: IdPhoto] isThumb:YES];
AFImageRequestOperation* imageOperation = [AFImageRequestOperation imageRequestOperationWithRequest: [NSURLRequest requestWithURL:imageURL] success:^(UIImage *image) {
//create an image view, add it to the view
UIImageView* thumbView = [[UIImageView alloc] initWithImage: image];
thumbView.frame = CGRectMake(0,0,90,90);
thumbView.contentMode = UIViewContentModeScaleAspectFit;
[self insertSubview: thumbView belowSubview: caption];
}];
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[queue addOperation:imageOperation];
}
return self;
}
#end

Refactor iOS ViewController to work without needing a nib

I wrote a nice gallery view controller .h .m and .xib that work fine for my purposes. Tap a programmatically created button and load an image, play a movie or view a pdf or website - while in an existing uinavigationcontroller. I want to change it so I can add the contents of the xib in code - without using the nib file. In this way it will be more useable (I think).
The problem is the functions in the .m that reference, for instance - [self presentMoviePlayerViewControllerAnimated:YES] etc do not work. I tried making a property of the rootviewcontroller in this new .h and .m and replacing self with myController (property name). But my view controller code relies on uinavigation existing to push new content or things like that. How can I remove/tweak these references to self or a reliance on uinavigationcontrollers so it will work like when it has a view controller for a nib?
Edit: Code added below. In the nib there is just a uiscrollview called uis_thumbScrollView. I would like to add this anywhere by simply calling something like:
[self.view addSubview:[[ebThumbScroller alloc] initWithFrame:CGRectMake(0, 0, 1024, 733)]];
Everyone's comments reminded me that the uiview this will be put in exists within the rootviewcontroller, over the top. Maybe this is why I can hear the movie playing - but not see it.
Note: The code creates a series of uiviews with buttons inside of a uiscrollview.
.h
#import
#import "ebAppDelegate.h"
#import "MediaPlayer/MediaPlayer.h"
#interface HomeGalleryViewController : UIViewController <UIScrollViewDelegate, UIGestureRecognizerDelegate, UIDocumentInteractionControllerDelegate> {
BOOL pageControlBeingUsed;
int buttonCount;
CGFloat _minimumColumnGap;
UIEdgeInsets _contentInsets;
NSInteger _colCount;
NSInteger _rowCount;
CGFloat _rowGap;
CGFloat _colGap;
UIEdgeInsets _effectiveInsets;
//int iGalleryThumbs;
//int iPlanThumbs;
int iTotalButtons;
ebAppDelegate *ebappdelegate;
ebGalleryItem *ebgalleryItem;
NSDictionary *gallDict;
NSArray *gallerySections;
NSArray *galleryArray;
NSMutableArray *nsm_gallArray;
UIDocumentInteractionController *controller;
}
//#property (nonatomic, retain) IBOutlet UIButton *bItem;
#property (nonatomic, retain) NSString *galleryNameString;
#property (nonatomic, retain) IBOutlet UIScrollView* scrollView;
#property (retain, nonatomic) NSMutableArray *arr_Views;
#property (strong, nonatomic) IBOutlet UIScrollView* uis_thumbScrollView;
#property (strong, nonatomic) IBOutlet UIPageControl* uis_pageControl;
#property (strong, nonatomic) IBOutlet UIView *uiv_thumbView;
#property (strong, nonatomic) MPMoviePlayerController *player;
#property (strong, nonatomic) MPMoviePlayerViewController *playerViewController;
- (IBAction)changePage;
- (IBAction) clickOpen:(id)sender;
- (void)playMovie:(NSString*)movieName;
- (void)movieFinishedCallback:(NSNotification*)_notification;
#end
.m
#import "HomeGalleryViewController.h"
#import "ebAppDelegate.h"
#import "GalleryImagesViewController.h"
#import "Gallery.h"
#import "GalleryThumbnailsViewController.h"
#import "GalleriesListViewController.h"
#import <QuartzCore/CoreAnimation.h>
#import "ebGalleryItem.h"
#import "WebViewController.h"
#implementation HomeGalleryViewController
// buttons
#define hGutter 17
#define vGutter 13
#define btnSize 130
#define topSpace 50
#define leftMargin 100
#synthesize uiv_thumbView;
#synthesize uiv_gallCat0, uiv_gallCat1, uiv_gallCat2,uiv_gallCat3, uiv_gallCat4, uiv_gallCat5,uiv_gallCat6;
#synthesize uis_thumbScrollView, uis_pageControl;
#synthesize galleryNameString,scrollView,arr_Views;
#synthesize player, playerViewController;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
ebappdelegate = (ebAppDelegate *)[[UIApplication sharedApplication] delegate];
arr_Views = [[NSMutableArray alloc] init];
self.scrollView.contentSize = CGSizeMake(1024, 1005);
// nsarray of dictionaries (galleries)
gallerySections = ebappdelegate.arr_galleryData;
NSLog(#"gallerySections count:%i",[gallerySections count]);
nsm_gallArray = [NSMutableArray arrayWithCapacity:1];
[self layoutGalleryThumbs];
}
#pragma mark
#pragma mark Layout Gallery Thumbs
-(void)layoutGalleryThumbs {
NSUInteger numGallSections = [gallerySections count];
NSLog(#"gallerySections data:%#",gallerySections);
NSLog(#"numGallSections count:%i",numGallSections);
// Window bounds.
CGRect bounds = CGRectMake(0, 0, 1024, 215);
for (int i=0; i<numGallSections; i++) {
// Create a view and add it to the window.
UIView* vview = [[UIView alloc] initWithFrame: CGRectMake(0, bounds.size.height*i-1, bounds.size.width, bounds.size.height)];
[vview setBackgroundColor: [UIColor whiteColor]];
[vview setTag:i];
//vview.backgroundColor = (UIColor (i % 2 == 0 ? cyanColor : whiteColor];
vview.backgroundColor = (i % 2 == 0)? [UIColor lightGrayColor] : [UIColor whiteColor];
[arr_Views addObject:vview];
// add line below at bottom
UIView* lineView = [[UIView alloc] initWithFrame: CGRectMake(280, bounds.size.height, 700, 2)];
[lineView setBackgroundColor: [UIColor grayColor]];
lineView.alpha = 0.5;
[vview addSubview:lineView];
[uis_thumbScrollView addSubview: vview];
NSLog(#"start===============i:%i",i);
// grab a gallery
gallDict = [gallerySections objectAtIndex:i]; // grab dict
galleryArray = [gallDict objectForKey:#"gallSectionData"]; // grab array from dict
NSLog(#"galleryArray:%#",[galleryArray description]);
NSString *secTitle = [gallDict objectForKey:#"gallSectionName"];
iTotalButtons = [galleryArray count];
NSLog(#"iTotalButtons count:%i",iTotalButtons);
_minimumColumnGap = 5;
_colCount = floorf((uis_thumbScrollView.bounds.size.width - _contentInsets.left - _contentInsets.right) / btnSize);
while (1) {
_colGap = (uis_thumbScrollView.bounds.size.width - _contentInsets.left - _contentInsets.right - btnSize * _colCount) / (_colCount + 1);
if (_colGap >= _minimumColumnGap)
break;
--_colCount;
};
_rowCount = (iTotalButtons + _colCount - 1) / _colCount;
_rowGap = _colGap;
_effectiveInsets = UIEdgeInsetsMake(_contentInsets.top + _rowGap,
_contentInsets.left + _colGap,
_contentInsets.bottom + _rowGap,
_contentInsets.right + _colGap);
NSLog(#"row count:%i",_rowCount);
NSLog(#"col count:%i",_colCount);
buttonCount=0;
for (int e=0; e<iTotalButtons; e++) {
NSLog(#"e:%i",e);
ebgalleryItem = [galleryArray objectAtIndex:e];
UIImage *thumbImg = [UIImage imageNamed:ebgalleryItem.gallThumb];
UIButton *button = [UIButton buttonWithType: UIButtonTypeCustom];
CGRect frame = CGRectMake (btnSize*e+leftMargin, topSpace,
btnSize-hGutter, btnSize-vGutter );
[button setFrame: frame];
NSLog(#"added button");
//[button setBackgroundImage:thumbImg forState:UIControlStateNormal];
[button setImage:thumbImg forState:UIControlStateNormal];
[button setTitle:ebgalleryItem.gallName forState:UIControlStateNormal];
NSLog(#"%#",button.titleLabel.text);
[button addTarget: NULL action:#selector(clickOpen:) forControlEvents:UIControlEventTouchUpInside];
UILongPressGestureRecognizer *tapAndHold = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longclickOpen:)];
[tapAndHold setMinimumPressDuration:0.33];
[button addGestureRecognizer:tapAndHold];
[button setTag:e];
//[button setTag:i*_colCount+e];
NSLog(#" button tag=%i", button.tag);
button.alpha=1.0;
[[arr_Views objectAtIndex:i] addSubview:button];
NSLog(#"middle====i:%i",i);
// caption label
CGRect labelFrame = CGRectMake( btnSize*e+leftMargin, 125,
btnSize-hGutter, btnSize-vGutter );
UILabel* label = [[UILabel alloc] initWithFrame: labelFrame];
[label setFont:[UIFont fontWithName:#"Arial" size:14]];
label.numberOfLines = 0;
[label setText:ebgalleryItem.gallCaption];
[label setTextColor: [UIColor blackColor]];
[label setTextAlignment:UITextAlignmentCenter];
[label setBackgroundColor:[UIColor clearColor]];
[[arr_Views objectAtIndex:i] addSubview: label];
NSLog(#"middle2====i:%i",i);
buttonCount++;
}
// Section Title label
CGRect titleLabelFrame = CGRectMake(btnSize,0,250,50);
UILabel* titlelabel = [[UILabel alloc] initWithFrame: titleLabelFrame];
[titlelabel setFont:[UIFont fontWithName:#"Arial" size:16]];
[titlelabel setText:secTitle];
[titlelabel setTextColor: [UIColor blackColor]];
[titlelabel setTextAlignment:UITextAlignmentLeft];
[titlelabel setBackgroundColor:[UIColor clearColor]];
[[arr_Views objectAtIndex:i] addSubview: titlelabel];
NSLog(#"end====i:%i",i);
CGFloat scrollViewHeight = 0.0f;
for (UIView* view in self.uis_thumbScrollView.subviews)
{
if (!view.hidden)
{
CGFloat y = view.frame.origin.y;
CGFloat h = view.frame.size.height;
if (y + h > scrollViewHeight)
{
scrollViewHeight = h + y;
}
}
}
[self.uis_thumbScrollView setContentSize:(CGSizeMake(self.uis_thumbScrollView.frame.size.width, scrollViewHeight+74))]; //74 is space from top in IB of scroll
}
uiv_thumbView.alpha = 1.0;
}
#pragma mark Scrollview
- (void)scrollViewDidScroll:(UIScrollView *)sender {
// Update the page when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.uis_thumbScrollView.frame.size.width;
int page = floor((self.uis_thumbScrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.uis_pageControl.currentPage = page;
// nslogs zoomsacle/bounds
CGRect visibleRect;
visibleRect.origin = uis_thumbScrollView.contentOffset;
visibleRect.size = uis_thumbScrollView.bounds.size;
float theScale = 1.0 / [uis_thumbScrollView zoomScale];
visibleRect.origin.x *= theScale;
visibleRect.origin.y *= theScale;
visibleRect.size.width *= theScale;
visibleRect.size.height *= theScale;
NSLog( #"Visible rect: %#", NSStringFromCGRect(visibleRect) );
}
- (IBAction)changePage {
// update the scroll view to the appropriate page
CGRect frame;
frame.origin.x = self.uis_thumbScrollView.frame.size.width * self.uis_pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.uis_thumbScrollView.frame.size;
[self.uis_thumbScrollView scrollRectToVisible:frame animated:YES];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
//===================================================================
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft | interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[self setUiv_thumbView:nil];
}
- (void)viewDidDisappear:(BOOL)animated {
}
- (void)viewWillAppear:(BOOL)animated {
[UIApplication sharedApplication].statusBarHidden = YES;
self.view.frame = [UIScreen mainScreen].applicationFrame;
CGRect frame = self.navigationController.navigationBar.frame;
frame.origin.y = 0;
self.navigationController.navigationBar.frame = frame;
[self.navigationController setNavigationBarHidden:YES animated:animated];
self.navigationController.navigationBar.translucent = YES;
}
- (void)viewWillDisappear:(BOOL)animated {
[UIApplication sharedApplication].statusBarHidden = NO;
CGRect frame = self.navigationController.navigationBar.frame;
frame.origin.y = 20.0;
self.navigationController.navigationBar.frame = frame;
}
- (void)viewDidAppear:(BOOL)animated {
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.navigationController setNavigationBarHidden:YES animated:animated];
[self.navigationController setToolbarHidden:YES animated:YES];
[super viewDidAppear:animated];
}
//======================================================================
-(IBAction)clickOpen:(id)sender {
UIButton *tmpBtn = (UIButton*)sender;
NSLog(#"sender tag: %i", [sender tag]);
int superviewTag = [sender superview].tag;
NSLog(#"sender superview tag: %i", superviewTag);
gallDict = [gallerySections objectAtIndex:superviewTag]; // grab dict
galleryArray = [gallDict objectForKey:#"gallSectionData"]; // grab array from dict
tmpBtn.alpha = 0.6;
ebgalleryItem = [galleryArray objectAtIndex:[sender tag]];
NSLog(#"%#",ebgalleryItem.gallType);
NSLog(#"%#",ebgalleryItem.gallName);
NSLog(#"gallDict %#",gallDict);
if ([ebgalleryItem.gallType isEqualToString:#"movie"]) {
[self playMovie:ebgalleryItem.gallFilm];
} else if ([ebgalleryItem.gallType isEqualToString:#"image"]) {
[self imageViewer:sender];
} else if ([ebgalleryItem.gallType isEqualToString:#"pdf"]) {
[self viewPDF:ebgalleryItem.gallName];
} else if ([ebgalleryItem.gallType isEqualToString:#"web"]) {
[self openWeb:ebgalleryItem.gallName];
}
}
#pragma mark
#pragma mark Open Websites
- (IBAction)openWeb:(NSString*)thisWEB {
WebViewController *webViewController = [[WebViewController alloc]
initWithNibName:#"WebViewController"
bundle:nil];
[webViewController socialButton:thisWEB];
webViewController.title = thisWEB;
[self presentModalViewController:webViewController animated:YES];
}
#pragma mark
#pragma mark Image Viewer
-(void)imageViewer:(id)sender {
UIButton *tmpBtn = (UIButton*)sender;
galleryNameString = tmpBtn.titleLabel.text;
tmpBtn.alpha = 0.6;
GalleryImagesViewController *vc = [[GalleryImagesViewController alloc] initWithGallery:[Gallery galleryNamed:galleryNameString]];
[vc goToPageAtIndex:0 animated:NO];
CATransition* transition = [CATransition animation];
transition.duration = 0.33;
transition.type = kCATransitionFade;
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer
addAnimation:transition forKey:kCATransition];
[self.navigationController pushViewController:vc animated:NO];
}
#pragma mark
#pragma mark PDF Viewer
-(void)viewPDF:(NSString*)thisPDF {
NSString *fileToOpen = [[NSBundle mainBundle] pathForResource:thisPDF ofType:#"pdf"];
NSURL *url = [NSURL fileURLWithPath:fileToOpen];
NSLog(#"%#",fileToOpen);
controller = [UIDocumentInteractionController interactionControllerWithURL:url];
[self previewDocumentWithURL:url];
}
- (IBAction) clickClose:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
- (void)previewDocumentWithURL:(NSURL*)url
{
UIDocumentInteractionController* preview = [UIDocumentInteractionController interactionControllerWithURL:url];
preview.delegate = self;
[preview presentPreviewAnimated:YES];
}
//======================================================================
- (void)documentInteractionControllerDidDismissOptionsMenu:(UIDocumentInteractionController *)controller{
}
//===================================================================
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
return self;
}
- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller
{
return self.view;
}
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller
{
return self.view.frame;
}
-(IBAction)longclickOpen:(UILongPressGestureRecognizer*)gesture {
if (gesture.state == UIGestureRecognizerStateBegan ) {
[self.navigationController setNavigationBarHidden:NO];
ebAppDelegate *appDelegate = (ebAppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.isFromLongPress=YES;
//NSUInteger i = [gesture.view tag];
//galleryNameString = [appDelegate.arr_galleryData objectAtIndex:i];
NSLog(#"load %#",galleryNameString);
UIButton *btn = (UIButton*)gesture.view;
galleryNameString = btn.titleLabel.text; btn.alpha = 0.6;
//NSLog(#"Long Press");
//NSLog(#"llongclickOpen");
UIViewController *vc = [[GalleryThumbnailsViewController alloc] initWithGallery:[Gallery galleryNamed:galleryNameString]];
CATransition* transition = [CATransition animation];
transition.duration = 0.33;
transition.type = kCATransitionFade;
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer
addAnimation:transition forKey:kCATransition];
[self.navigationController pushViewController:vc animated:NO];
}
}
-(void)playMovie:(NSString*)movieName {
NSString *url = [[NSBundle mainBundle]
pathForResource:movieName
ofType:#"m4v"];
NSLog(#"%#",movieName);
playerViewController = [[MPMoviePlayerViewController alloc]
initWithContentURL:[NSURL fileURLWithPath:url]];
[[NSNotificationCenter defaultCenter] removeObserver:playerViewController
name:MPMoviePlayerPlaybackDidFinishNotification
object:playerViewController.moviePlayer];
// Register this class as an observer instead
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:playerViewController.moviePlayer];
[self.view insertSubview:playerViewController.view atIndex:50];
//---play movie---
player = [playerViewController moviePlayer];
player.controlStyle = MPMovieControlStyleFullscreen;
player.repeatMode=MPMovieRepeatModeOne;
[self presentMoviePlayerViewControllerAnimated:playerViewController];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[super viewDidLoad];
}
- (void)movieFinishedCallback:(NSNotification*)aNotification {
// Obtain the reason why the movie playback finished
NSNumber *finishReason = [[aNotification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
// Dismiss the view controller ONLY when the reason is not "playback ended"
if ([finishReason intValue] != MPMovieFinishReasonPlaybackEnded)
{
MPMoviePlayerController *moviePlayer = [aNotification object];
// Remove this class from the observers
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
// Dismiss the view controller
[self dismissModalViewControllerAnimated:YES];
}
}
#end
If your only problem is the not working [self presentMoviePlayerViewControllerAnimated:YES] method, the problem is that presentMoviePlayerViewControllerAnimated: requires the actual moviePlayerViewController as an argument not a boolean value. (assuming you're refering to this method of the UIViewController category) UIViewController MediaPlayer Additions Reference
So if you replace that by say presentMoviePlayerViewControllerAnimated:self.moviePlayerVC, it should work as expected.
I'm not sure I understand your question, but if you need to wrap your controller to some UINavigationController you can do it like this:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myController];
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
navController.navigationBar.barStyle = UIBarStyleBlack;
[self presentViewController:navController animated:YES completion:^{
//
}];
later on any child controller will have the navigation hierarchy.

Resources