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
Related
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.
I have been doing an Project for IOS which is written in Objective C. Theres a requirement where i have to put a Button or Label below a table view which kind of act as an Dialog like view over an WebView. There is already an header view embedded into the table view, its work well, but when i try to place the button or label below the table view using Storyboard its not working as expected it actually not positioning below the TableView. Below is the image how my View is laid out :
This is how it looks currently :
Below is the code for my view controller :
ViewController.h:
#import "FlatUIKit.h"
#interface NothiViewController : UIViewController
{
IBOutlet UIWebView *mainWebView;
IBOutlet UISegmentedControl *segmentControl;
IBOutlet UIView *viewNothiPermittedUsers;
IBOutlet UILabel *labelTitleNothiPermittedUsers;
IBOutlet UITableView *tableViewNothiPermittedUsers;
}
#property (nonatomic,strong) NSArray *arrNothiPermittedUsers;
#property(nonatomic,retain) ModelNothi *currentModelNothi;
- (void)updateRightBar:(BOOL)all;
#end
#interface CellNothiPermittedUserList : UITableViewCell
{
}
#property (nonatomic, strong) IBOutlet UILabel *labelUserName;
#property (nonatomic, strong) IBOutlet FUIButton *buttonSend;
#end
ViewController.m:
#interface NothiViewController ()<UIWebViewDelegate,CustomAlertViewDelegate>
{
RequestNothiActionApiType currentNothiActionApiType;
AlertType currentAlertType;
}
#property(nonatomic,strong)NSData *dataNotangsho;
#property(nonatomic,strong)NSData *dataPotrangsho;
#end
#implementation NothiViewController
#synthesize currentModelNothi;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = APP_VIEW_BACKGROUND_COLOR;
mainWebView.delegate = self;
mainWebView.backgroundColor = UIColor.clearColor;
mainWebView.opaque = YES;
mainWebView.scalesPageToFit = YES;
UIFont *font = [UIFont systemFontOfSize:16.0f];
NSDictionary *attributes = [NSDictionary dictionaryWithObject:font
forKey:NSFontAttributeName];
[segmentControl setTitleTextAttributes:attributes
forState:UIControlStateNormal];
segmentControl.tintColor = COLOR_LOGIN_BUTTON;
self.dataNotangsho = nil;
self.dataPotrangsho = nil;
currentNothiActionApiType = API_TYPE_NOTANGSHO;
NSDictionary *params = #{#"data_ref": #"api",
#"api_key": API_KEY,
#"user_designation": [AppSupporter sharedInstance].currentDesignationID};
NSString *api = [NSString stringWithFormat:#"%#/%#",API_NOTHI_NOTANGSHO,self.currentModelNothi.nothiParts];
CGRect frame = segmentControl.frame;
frame.origin.y = NAV_BAR_HEIGHT + STATUS_BAR_HEIGHT;
segmentControl.frame = frame;
segmentControl.backgroundColor = APP_VIEW_BACKGROUND_COLOR;
// Delay execution of my block for 10 seconds.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self connectServer:api withParams:params withProgressMessage:#"তথ্য লোড হচ্ছে, একটু অপেক্ষা করুন..."];
});
viewNothiPermittedUsers.hidden = YES;
viewNothiPermittedUsers.backgroundColor = [UIColor colorWithWhite:0.0F alpha:0.7f];
labelTitleNothiPermittedUsers.backgroundColor = [UIColor lightGrayColor];
[labelTitleNothiPermittedUsers.layer setCornerRadius:8.0f];
labelTitleNothiPermittedUsers.layer.masksToBounds = YES;
labelTitleNothiPermittedUsers.font = [UIFont boldFlatFontOfSize:16.0f];
tableViewNothiPermittedUsers.backgroundColor = [UIColor whiteColor];
tableViewNothiPermittedUsers.tableFooterView = [[UIView alloc] initWithFrame : CGRectZero];
[tableViewNothiPermittedUsers.layer setCornerRadius:8.0f];
tableViewNothiPermittedUsers.layer.masksToBounds = YES;
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(notifyNothiForward:) name:EventNothiForward object:nil];
}
Any help would be highly appreciated. Note i am kind of new to IOS programming and the project was written by someone else, which i just got now to extend it, so i am little aware of positioning views at the moment.
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
I am trying to build a gantt chart.
I found this library on https://github.com/evolvIQ/iqwidgets
I download it, I tried to understand how can I use it.
I have a class that bring the data(JSON) from a server. I am assigning these results as [NSDictionary].
I tried to use the IQGanttView.h file by adding it as a subview of my current view.
IQGanttView.h has a method called addRow:(id<IQCalendarDataSource>)row
The addRow method has an argument of IQCalendarDataSource which is why I created a class as an IQCalendarDataSource (Task object).
I change the IQCalendarDataSource class to have the same property of my task class.
After creating these tasks object, I have a for loop for all the array(tasks object) to add them through addRow:(id<IQCalendarDataSource>)row method to show up on the chart.
I ran the code and followed it but it's not showing me the tasks on the chart.
I don't know if i'm missing something?
Can someone check the library and tell me if i'm missing something?
=================
This is the code that I was trying.
#import "GanttChartViewController.h"
#import "ASRESTAPI.h"
#import "ASUserSingleton.h"
#import "TasksObj.h"
#import "IQGanttView.h"
// when the view load I want to show the user the loading view until the data is ready to show up on the chart by calling [self setupLoadingIndicator] method
//
- (void)viewDidLoad {
[super viewDidLoad];
tasksItems = [[NSArray alloc] init];
self.ganttView = [[IQGanttView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.ganttView];
[self setupLoadingIndicator];
// Do any additional setup after loading the
[self gettheTasksItems];
}
-(void)setupLoadingIndicator
{
loadingView = [[UIView alloc] initWithFrame:CGRectMake(75, 155, 170, 170)];
loadingView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
loadingView.clipsToBounds = YES;
loadingView.layer.cornerRadius = 10.0;
activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityView.frame = CGRectMake(65, 40, activityView.bounds.size.width, activityView.bounds.size.height);
[loadingView addSubview:activityView];
loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 115, 130, 22)];
loadingLabel.backgroundColor = [UIColor clearColor];
loadingLabel.textColor = [UIColor whiteColor];
loadingLabel.adjustsFontSizeToFitWidth = YES;
loadingLabel.textAlignment = NSTextAlignmentCenter;
loadingLabel.text = #"Loading...";
[loadingView addSubview:loadingLabel];
[self.ganttView addSubview:loadingView];
[activityView startAnimating];
}
-(void)gettheTasksItems
{
NSString* username = [[ASUserSingleton sharedInstance]userName];
NSString* password = [[ASUserSingleton sharedInstance]password];
_tasks = nil;
[ASRESTAPI tasksListUsername:username andPassword:password completionBlock:^(NSDictionary *response, NSArray *taskArray) {
_tasks = response;
tasksItems = taskArray;
NSMutableArray *tasksObjs = [NSMutableArray array];
int i;
for (i =0; i < tasksItems.count;i++)
{
/*_tasks[#"project"][#"name"]*/ // this is how to call the dictionary object from the array
TasksObj* tasksObj = [[TasksObj alloc]initWithProjectName:tasksItems[i][#"project"][#"name"]
startDate:tasksItems[i][#"start_date"]
dueDate:tasksItems[i][#"due_date"]
estimatedhours:tasksItems[i][#"estimated_hours"]];
//tasksItems[i] objectForKey:#"project"];
[tasksObjs addObject:tasksObj];
}
dispatch_async(dispatch_get_main_queue(), ^{
[activityView stopAnimating];
for (loadingView in [self.ganttView subviews])
{
[loadingView removeFromSuperview];
}
//[loadingView removeFromSuperview];
for (TasksObj* tasksObj in tasksObjs) {
[self.ganttView addRow:tasksObj];
}
});
}];
}
The reason that I'm using dispatch_async(dispatch_get_main_queue() is to make sure that the UI element is shown, i've learned that if I want the UI element to be shown then I have to make it through the main queue.
This is the class of TasksObj
#interface TasksObj : NSObject <IQCalendarDataSource>
#property (nonatomic, strong) NSString* projectName;
#property (nonatomic, strong) NSDate* start_date;
#property (nonatomic, strong) NSDate* due_date;
#property (nonatomic, strong) NSNumber* estimated_hours;
-(id)initWithProjectName:(NSString*)projectName startDate:(NSDate*)start_date dueDate:(NSDate*)due_date estimatedhours:(NSNumber*)estimated_hours;
#end
#implementation TasksObj
-(id)initWithProjectName:(NSString*)projectName startDate:(NSDate*)start_date dueDate:(NSDate*)due_date estimatedhours:(NSNumber*)estimated_hours
{
self = [super init];
if (self) {
self.projectName = projectName;
self.start_date = start_date;
self.due_date = due_date;
self.estimated_hours = estimated_hours;
}
return self;
}
#end
by the way this is the JSON data that i'm getting from the server
"task":
{
"id":1,
"project":{"id":1,"name":"test"},
"tracker":{"id":1,"name":"Bug"},
"status":{"id":1,"name":"New"},
"priority":{"id":4,"name":"Urgent"},
"author":{"id":1,"name":"the user name"},
"subject":"Example",
"description":"",
"start_date":"2016-02-17",
"due_date":"2016-02-23",
"done_ratio":0,
"estimated_hours":3.0,
"spent_hours":0.0,
"created_on":"2016-02-18T04:28:55Z",
"updated_on":"2016-02-22T19:09:22Z"
}
I am trying to call another method with Delegate and protocols in my app. I need to send the variable "myData" to another view but for some reasons it doesn't works. I don't know what I am doing wrong with the implementation of delegates and protocols. The delegate never call the action of the protocol.
Sorry I'm new with this.
BLEViewController.h
#import <UIKit/UIKit.h>
#import "BLE.h"
#protocol EnviarDatos <NSObject>
//Metodo que se manda llamar pero se implementa en otra clase
-(void) actualizaDatos:(NSData*)Data;
#end
#interface BLEViewController : UITableViewController <BLEDelegate>
{
//id <EnviarDatos> delegate;
}
#property (nonatomic,assign)id delegate;
#property (nonatomic, retain) NSData *myData;
+ (BLE*) theBLEObject;
- (void) scanForPeripherals;
- (IBAction)connect:(id)sender;
-(void) activaProtocolo;
#end
BLEViewController.m
//
// BLEViewController.m
// DL_RemoteBLE_02
//
// Created by Dave Lichtenstein on 3/16/14.
// Copyright (c) 2014 Dave Lichtenstein. All rights reserved.
//
#import "BLEViewController.h"
static BLE* ble;
static UILabel *statusLabel;
static NSString* connectionStatus = #"Not connected!";
#interface BLEViewController ()
#end
#implementation BLEViewController
#synthesize delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
if(ble==nil)
{
// Create our Bluetooth Low Energy object
//
ble = [[BLE alloc] init];
[ble controlSetup];
ble.delegate = self;
}
// Create a toolbar at the bottom of the screen to show status text, etc.
//
// get screen size
//
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
CGFloat toolbarHeight = 50.0;
CGFloat labelHeight = 50.0;
if(statusLabel==nil) // only create once
{
// create our status label object
//
statusLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, screenHeight-toolbarHeight-labelHeight, screenWidth, labelHeight)];
statusLabel.backgroundColor = [UIColor clearColor];
statusLabel.textColor = [UIColor blackColor];
statusLabel.font = [UIFont boldSystemFontOfSize:15];
statusLabel.text = #"Connection Status:";
}
// create a toolbar
//
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0,screenHeight-toolbarHeight,screenWidth,toolbarHeight)];
toolbar.tintColor = [UIColor blackColor];
/*UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 150, 20)];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor blackColor];
label.font = [UIFont boldSystemFontOfSize:15];
label.text = #"Status:";
UIBarButtonItem *labeltext = [[UIBarButtonItem alloc] initWithCustomView:label];
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithTitle:#"" style:UIBarButtonItemStyleDone target:self action:nil];
NSArray *items = [NSArray arrayWithObjects:statusLabel, nil];
toolbar.items = items;
*/
[self.view addSubview:statusLabel];
[self.view addSubview:toolbar];
// Update our status label
statusLabel.text = connectionStatus;
_myData = [[NSData alloc]init];
delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//-------------------------------------------------------
// methods
/////////////////////////////////////////////////////////
+ (BLE*) theBLEObject
{
return ble;
}
-(void) connectionTimer:(NSTimer *)timer
{
if (ble.peripherals.count > 0)
{
[ble connectPeripheral:[ble.peripherals objectAtIndex:0]];
}
NSLog(#"connectionTimer"); // diag
}
// We call this when the view loads to try to connect to our bluetooth perepheral
//
- (void) scanForPeripherals
{
if (ble.activePeripheral)
if(ble.activePeripheral.state == CBPeripheralStateConnected)
{
statusLabel.text = #"Disconnectng from peripheral...";
[[ble CM] cancelPeripheralConnection:[ble activePeripheral]];
return;
}
if (ble.peripherals)
ble.peripherals = nil;
NSLog(#"scanning...");
statusLabel.text = #"Scanning for peripherals...";
[ble findBLEPeripherals:2];
[NSTimer scheduledTimerWithTimeInterval:(float)2.0 target:self selector:#selector(connectionTimer:) userInfo:nil repeats:NO];
//[indConnecting startAnimating];
}
- (IBAction)connect:(id)sender {
[self scanForPeripherals];
}
///////////////////////////////////////////////////////////
#pragma mark - BLE delegate
///////////////////////////////////////////////////////////
NSTimer *rssiTimer;
// When Connected, this will be called
-(void) bleDidConnect
{
NSLog(#"->Connected");
statusLabel.text = #"Connected!";
connectionStatus = #"Connected!";
// Schedule to read RSSI every 1 sec.
rssiTimer = [NSTimer scheduledTimerWithTimeInterval:(float)1.0 target:self selector:#selector(readRSSITimer:) userInfo:nil repeats:YES];
}
// When RSSI is changed, this will be called
-(void) bleDidUpdateRSSI:(NSNumber *) rssi
{
// Append the rssi value to our status label
//
NSString *temp = [NSString stringWithFormat:#"%# (%#)", connectionStatus, rssi];
statusLabel.text = temp;
}
-(void) readRSSITimer:(NSTimer *)timer
{
[ble readRSSI];
}
// When data is comming, this will be called
-(void) bleDidReceiveData:(unsigned char *)data length:(int)length
{
NSData *d = [NSData dataWithBytes:data length:length];
_myData = [NSData dataWithBytes:data length:length];
NSString *s = [[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding];
NSLog(#"Datos en String %#",s);
//_datosdelegate = self;
//Is anyone listening
if([delegate respondsToSelector:#selector(actualizaDatos:)])
{
//send the delegate function with the amount entered by the user
[delegate actualizaDatos:_myData];
NSLog(#"Entro delegado");
}
}
- (void)bleDidDisconnect
{
NSLog(#"->Disconnected");
connectionStatus = #"Disconnected!";
statusLabel.text = #"Disconnected!";
[rssiTimer invalidate];
}
#end
sevenSegmentsViewController.h
#import <UIKit/UIKit.h>
#import "BLEViewController.h"
#import "BLE.h"
#interface sevenSegmentsViewController : UIViewController<EnviarDatos>{
UIImage *unoON;
UIImage *dosON;
UIImage *tresON;
UIImage *cuatroON;
UIImage *cincoON;
UIImage *seisON;
UIImage *sieteON;
UIImage *unoOFF;
UIImage *dosOFF;
UIImage *tresOFF;
UIImage *cuatroOFF;
UIImage *cincoOFF;
UIImage *seisOFF;
UIImage *sieteOFF;
}
#property (strong, nonatomic) IBOutlet UIImageView *uno;
#property (strong, nonatomic) IBOutlet UIImageView *dos;
#property (strong, nonatomic) IBOutlet UIImageView *tres;
#property (strong, nonatomic) IBOutlet UIImageView *cuatro;
#property (strong, nonatomic) IBOutlet UIImageView *cinco;
#property (strong, nonatomic) IBOutlet UIImageView *seis;
#property (strong, nonatomic) IBOutlet UIImageView *siete;
#end
sevenSegmentsViewController.m
//
// sevenSegmentsViewController.m
// iShield
//
// Created by Victor Carreño on 29/03/14.
// Copyright (c) 2014 RedBearLab. All rights reserved.
//
#import "sevenSegmentsViewController.h"
#interface sevenSegmentsViewController ()
#end
#implementation sevenSegmentsViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
unoOFF = [UIImage imageNamed:#"7segnh.png"];
dosOFF = [UIImage imageNamed:#"7segnv.png"];
tresOFF = [UIImage imageNamed:#"7segnv.png"];
cuatroOFF =[UIImage imageNamed:#"7segnh.png"];
cincoOFF = [UIImage imageNamed:#"7segnh.png"];
seisOFF = [UIImage imageNamed:#"7segnv.png"];
sieteOFF = [UIImage imageNamed:#"7segnh.png"];
unoON = [UIImage imageNamed:#"7segvh.png"];
dosON = [UIImage imageNamed:#"7segvv.png"];
tresON = [UIImage imageNamed:#"7segvv.png"];
cuatroON =[UIImage imageNamed:#"7segvh.png"];
cincoON = [UIImage imageNamed:#"7segvh.png"];
seisON = [UIImage imageNamed:#"7segvv.png"];
sieteON = [UIImage imageNamed:#"7segvh.png"];
_uno = [[UIImageView alloc]initWithImage:unoOFF];
_dos = [[UIImageView alloc]initWithImage:dosOFF];
_tres = [[UIImageView alloc]initWithImage:tresOFF];
_cuatro = [[UIImageView alloc]initWithImage:cuatroOFF];
_cinco = [[UIImageView alloc]initWithImage:cincoOFF];
_seis = [[UIImageView alloc]initWithImage:seisOFF];
_siete = [[UIImageView alloc]initWithImage:sieteOFF];
//BLEViewController *myBLE = [[BLEViewController alloc]init];
//BLE *myBLE = [BLEViewController theBLEObject];
//NSLog(#"%#", myBLE.myData);
BLEViewController *myBLE = [[BLEViewController alloc]init];
myBLE.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#pragma mark Delegado de Actualizar datos
-(void) actualizaDatos :(NSData *)myData{
NSLog(#"Datos recividos");
NSLog(#"Imprimio mi data con exitos %#", myData);
}
#end
In a nutshell, your BLEViewController is setting its delegate property to "self" when I think you want it to get set to an instance of "sevenSegmentsViewController". As a result the "if([delegate respondsToSelector:..." test is failing and you are never hitting the call to actualizaDatos. If you are using protocols correctly, you don't really need to test for "respondsToSelector" because by definition, the delegate must support the protocol.
The compiler and IDE are not showing you the error because you declared the property of the BLEViewController as just type "id" instead of
id<EnviarDatos>
If you fix the property declaration to say that your delegate must support the right protocol, you'll immediately see the errors highlighted.