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"
}
Related
I have a subclass of UIView called InvitedView. It is instantiated in viewDidLoad like this:
ViewController.m
invitedView = [[InvitedView alloc] initWithFrame:CGRectMake(100, 244, 120, 80)];
invitedView.backgroundColor = [UIColor colorWithRed:156.0f/255.0f green:214.0f/255.0f blue:215.0f/255.0f alpha:0.9f];
[self.view addSubview:invitedView];
[invitedView setHidden:YES];
The class itself looks like this:
InvitedView.m
#import "InvitedView.h"
#import "AppDelegate.h"
#import "ViewController.h"
#class ViewController;
#interface InvitedView() {
UIButton *accept;
UIButton *decline;
UILabel *question;
UIView *gray;
ViewController *myViewController;
}
#end
#implementation InvitedView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
gray = [[UIView alloc] initWithFrame:frame];
NSString *holduser = [(AppDelegate*)[[UIApplication sharedApplication] delegate] invitedby];
[self addSubview:gray];
accept = [[UIButton alloc] init];
decline = [[UIButton alloc] init];
question = [[UILabel alloc] init];
question.text = [[NSString alloc] initWithFormat:#"You have been invited to a group game by %#", holduser];
question.numberOfLines = 0;
question.textAlignment = NSTextAlignmentCenter;
question.textColor = [UIColor colorWithRed:211.0f/255.0f green:243.0f/255.0f blue:219.0f/255.0f alpha:1.0f];
accept.backgroundColor = [UIColor clearColor];
accept.frame = CGRectMake(20, gray.frame.size.height / 2, (gray.frame.size.width / 2) - 10, (gray.frame.size.height / 2) - 20);
decline.backgroundColor = [UIColor clearColor];
decline.frame = CGRectMake((gray.frame.size.width / 2) + 10, (gray.frame.size.width / 2) - 20, (gray.frame.size.width / 2) - 20, (gray.frame.size.height / 2) - 20);
question.frame = CGRectMake(20, 20, gray.frame.size.width, (gray.frame.size.height / 2) - 20);
[question setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:18.0]];
[accept addTarget:myViewController action:#selector(acceptInvite) forControlEvents:UIControlEventTouchUpInside];
[decline addTarget:myViewController action:#selector(declineInvite) forControlEvents:UIControlEventTouchUpInside];
[gray addSubview:accept];
[gray addSubview:decline];
[gray addSubview:question];
}
return self;
}
#end
The method where the view is supposed to be shown is in the view controller showing the view. It ends up getting called, I can verify that the log messages happen all the way up until the setHidden function:
ViewController.m
- (void)doSomethingWithTheNewValueOfFlagForHid {
NSLog(#"issettingtheview******");
dispatch_async(dispatch_get_main_queue(), ^(void){
NSLog(#"issettingtheviewmu2******");
[invitedView setHidden:NO];
});
}
I would like to know why invitedView isn't being shown after [invitedView setHidden:NO].
It gets all the way to setHidden, and then nothing happens. I would appreciate any help, thanks in advance.
In ViewDidLoad, change line to
[invitedView setHidden:NO];
to make sure you can actually see the view (frame is ok, no view above ...)
You might also want to check Xcodes 3D View Debugging
The only reason that it wasn't showing up, is that invitedView was being instantiated inside an if statement that wasn't being executed. However - shallowThought's idea to switch setHidden to YES started me down a more productive debugging tract, leading to the discovery.
I'm using a contact picker to grab a string, then pass that string to another view controller, however the UILabel is not updating with the data (or any other string).
In the SlingViewController.m logs below, _taggedFriendsNames is being passed successfully.
Perhaps the issue is because the receiving view controller is trying to update the label on another (SlingshotView) view? I don't think that's the case as I've been updating labels in this way in other methods.
The answer is likely related to updating UILabels in general, but I've had no luck after searching.
Things I've checked with no success:
Updating from the main thread asynchronously
#synthesize the label in SlingshotView
calling setDisplay
Included potentially relevant code below. Thanks in advance for any tips!
SlingViewController.m
-(void)updateFriendsPickedLabel:(id)sender {
NSLog(#"updateFriendsPickedLabel: %#", _taggedFriendsNames); // i see this
slingshotView.friendsPickedLabel.text = #"any string"; // i don't see this
}
SlingViewController.h
#class TBMultiselectController;
#class SlingshotView;
#interface SlingViewController : UIViewController
#property (nonatomic, readonly) SlingshotView *slingshotView;
#property(nonatomic) NSString *taggedFriendsNames;
//for friend picker
-(void)updateFriendsPickedLabel:(id)sender;
#end
MultiSelectViewController.m
- (IBAction) sendButton: (id) sender {
NSMutableString *myString = [[NSMutableString alloc]initWithString:#""];
for (int i=0; i < self.selectedContacts.count; i++) {
Contact *myContact = self.selectedContacts[i];
[myString appendString:[NSString stringWithFormat:#"%# %# ", myContact.firstName, myContact.lastName]];
}
SlingViewController *svc = [[SlingViewController alloc] init];
svc.taggedFriendsNames = myString;
[svc updateFriendsPickedLabel:self];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
MultiSelectViewController.h
#protocol TBMultiselectControllerDelegate;
#class SlingViewController;
#interface TBMultiselectController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, TBContactsGrabberDelegate>
#property (nonatomic, assign) id<TBMultiselectControllerDelegate> delegate;
- (IBAction)sendButton: (id) sender;
#end
#protocol TBMultiselectControllerDelegate <NSObject>
-(void)updateFriendsPickedLabel:(id)sender;
#end
SlingshotView.h
#property (strong, nonatomic) UILabel *friendsPickedLabel;
SlingshotView.m
#synthesize friendsPickedLabel;
...
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGRect imageFrame = CGRectMake(0, 0, screenRect.size.width, screenRect.size.height);
contentView = [[UIView alloc] initWithFrame:frame];
[contentView setBackgroundColor:[UIColor whiteColor]];
[contentView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
[self addSubview:contentView];
self.friendsPickedLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, screenRect.size.height/2-100, screenRect.size.width-20, 200)];
self.friendsPickedLabel.shadowColor = [UIColor darkGrayColor];
self.friendsPickedLabel.numberOfLines = 0;
self.friendsPickedLabel.shadowOffset = CGSizeMake(0.5, 0.5);
self.friendsPickedLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.0];
[self.friendsPickedLabel setTextAlignment:NSTextAlignmentLeft];
self.friendsPickedLabel.textColor = [UIColor whiteColor];
self.friendsPickedLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:24];
[contentView addSubview:self.friendsPickedLabel];
You are reallocating this..
SlingViewController *svc = [[SlingViewController alloc] init];
svc.taggedFriendsNames = myString;
[svc updateFriendsPickedLabel:self];
Meaning your
slingshotView.friendsPickedLabel becomes nil..
And you are calling/using the delegate the wrong way, i think it suppose to be
[self.delegate updateFriendsPickedLabel:#"YourData To be Passed"];
From your code you are using the -(void)updateFriendsPickedLabel:(id)sender; inside SlingViewController and not the delegate, you are not implementing the delegate either..
Yes the -(void)updateFriendsPickedLabel:(id)sender; method is called, bacause you are calling it directly from the class..
SlingViewController.h
#interface SlingViewController : UIViewController < TBMultiselectControllerDelegate > // for delegate implementation
#property (nonatomic, readonly) SlingshotView *slingshotView;
#property(nonatomic) NSString *taggedFriendsNames;
//for friend picker
//-(void)updateFriendsPickedLabel:(id)sender;
#end
MultiSelectViewController.m
- (IBAction) sendButton: (id) sender {
NSMutableString *myString = [[NSMutableString alloc]initWithString:#""];
for (int i=0; i < self.selectedContacts.count; i++) {
Contact *myContact = self.selectedContacts[i];
[myString appendString:[NSString stringWithFormat:#"%# %# ", myContact.firstName, myContact.lastName]];
}
/*
SlingViewController *svc = [[SlingViewController alloc] init];
svc.taggedFriendsNames = myString;
[svc updateFriendsPickedLabel:self];
*/
[self.delegate updateFriendsPickedLabel:#"YourString"];
// this will call the method in your implementation class
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
Hmm.. I Think you have implemented the delegates the wrong way.
This is suppose to be a comment but its too long..
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
I have a custom uiview where i have a setter and a getter when the uiview is dynamically created i set this value like this:
for(NSDictionary *dictCategory in arrCategoryList)
{
NSString *strCategoryId = [dictCategory objectForKey:#"CategoryId"];
NSString *strCategoryName = [dictCategory objectForKey:#"Name"];
NSLog(#"%# : %#",strCategoryId,strCategoryName);
UIViewMenuItem *linkMenu = [[UIViewMenuItem alloc] init];
[linkMenu setFrame:CGRectMake(10, i+1, 300, 35)];
[linkMenu setId:strCategoryId]; //here i set the value in the custom uiview
linkMenu.layer.zPosition = 7;
[viewSlide3 addSubview:linkMenu];
[linkMenu setBackgroundColor:[UIColor blueColor]];
linkMenu.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.9];
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[linkMenu addGestureRecognizer:singleFingerTap];
UILabel *labelMenu = [[UILabel alloc] init];
[labelMenu setFrame:CGRectMake(20, 0, 300, 35)];
[labelMenu setFont:[UIFont systemFontOfSize:16]];
[labelMenu setTextColor:[UIColor whiteColor]];
[linkMenu addSubview:labelMenu];
[labelMenu setText:strCategoryName];
i = i + 35 + 1;
}
Now when i tap on the custom uiview i want to get back the value from the custom uiview so I'm doing this:
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
CGPoint location = [recognizer locationInView:[recognizer.view superview]];
CGPoint touchPoint=[recognizer locationInView:[recognizer.view superview]];
UIViewMenuItem *tempView = (UIViewMenuItem *)recognizer.view;
NSNumber *tag = [NSNumber numberWithInt:tempView.tag];
NSString *idCat = [tempView getCatId];
NSLog(#"TAG %#",idCat);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString: [NSString stringWithFormat:#"http://localhost:8888/MAMP/WHFC/SubCategories.php?categoryid=%d", idCat]]];
int i = 0;
NSError *e;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&e];
NSArray *arrCategoryList = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&e];
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor whiteColor];
UIView *uiView = [[UIView alloc] init];
[uiView setFrame:CGRectMake(0, 480, 320, 480)];
[uiView setBackgroundColor:[UIColor grayColor]];
viewController.view = uiView;
UITableView *uiTableView = [[UITableView alloc] init];
[uiTableView setFrame:CGRectMake(0, 0, 320, 480)];
[uiView addSubview:uiTableView];
[self presentViewController:viewController animated:YES completion:nil];
//Do stuff here...
}
But i keep get the same value "13" from NSString *idCat = [tempView getCatId];
This is the custom UIView class:
#import <UIKit/UIKit.h>
#interface UIViewMenuItem : UIView
- (void) setId: (NSString *) cId;
- (NSString *) getCatId;
#end
NSString *catId;
#import "UIViewMenuItem.h"
#implementation UIViewMenuItem
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (void) setId: (NSString *) cId;
{
catId = cId;
//If possible, set things up for the new word
}
- (NSString *) getCatId{
return catId;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
There is nothing wrong, in principle, with using a hidden (not visible from outside the class) instance variable cId and providing getters and setters.
But yours isn't an instance variable. It is declared somewhere between the interface and the implementation. It's a global variable or static. (I am not 100% positive about the global, but I think it is. I ran into a linker issue - dublicate object - once when I did the same mistake and did it in two classes using the same variable name. However, it is not that important whether it is global or just static. Being static is bad enough.)
This means at least that all the instances of UIViewMenuItem share the same variable (!!!).
First:
Move it to somewhere between #implementation and its #end.
Then it should work as expected.
Then:
Be lazy and solve it the objective-c-way. Get rid of the variable and get rid of the getter and setter.
If you are happy with the variable being public (it's accessible though getter and setter anyway) then just add a #property (nonatomic, retain) NSString *cid; to the interface. Unless you've got an older compiler then that is basically it. The compiler will add a getter and a setter (getCId and cId) automatically.
The compiler will add an iVar _cId that you would not use yourself in most cases. I am not 100% positive whether the name of the iVar will be cId or _cId when you use the comfortable way. If you care then you can conrol the name of the iVar by adding an #synthesize statment to the implementation and define the iVar name as you like. You could add much more customization (again declaring the iVar yourself, providing custom getters and setters) but there is no need for that when all you need from the property is what you have shown in your question and its code examples.
I have a class call Post and its a view....i add it some times in my main view like this:
take a lock how to remove and release this object from my self.view....
i just have this class:
#interface Post : UIView{
UILabel * label1;
UILabel * label2;
UILabel * label3;
}
#implementation Post
-(void)init
{
self = [super init];
if (self) {
label1 = [[UILabel alloc]init];
label2 = [[UILabel alloc]init];
label3 = [[UILabel alloc]init];
label1.frame = CGRect(10,10,100,30);
label2.frame = CGRect(10,60,100,30);
label3.frame = CGRect(10,110,100,30);
}
return self;
}
#end
and this main class controller
#implementation HomeViewController
-(void)viewDidLoad{
Post *p = [[Post alloc]init]
p.frame = CGRect(0,0,0,320,460);
p.backgroundColor = [UIColor blue];
[self.view addsubview: p];
[p release];
Post *p2 = [[Post alloc]init]
p2.frame = CGRect(0,0,0,320,460);
p2.backgroundColor = [UIColor blue];
[self.view addsubview:p2];
[p2 release];
Post *p3 = [[Post alloc]init]
p3.frame = CGRect(0,0,0,320,460);
p3.backgroundColor = [UIColor blue];
[self.view addsubview:p3];
[p3 release];
}
-(void)RemoveAllPosts
{
//How to remove and release all post from self.view???
}
#end
Please try below lines of code.
for(UIView *viewInner in self.view.subviews) {
if([viewInner isKindOfClass:[Post class]])
[viewInner removeFromSuperview];
}