Skip to content

Commit

Permalink
Make the week view events draggable.
Browse files Browse the repository at this point in the history
  • Loading branch information
muhku committed Jul 5, 2012
1 parent 377c761 commit 34621d6
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
11 changes: 10 additions & 1 deletion Classes/Example/WeekViewExampleController.m
Expand Up @@ -110,13 +110,22 @@ - (MAEvent *)event {

- (void)weekView:(MAWeekView *)weekView eventTapped:(MAEvent *)event {
NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:event.start];
NSString *eventInfo = [NSString stringWithFormat:@"Hour %i. Userinfo: %@", [components hour], [event.userInfo objectForKey:@"test"]];
NSString *eventInfo = [NSString stringWithFormat:@"Event tapped: %02i:%02i. Userinfo: %@", [components hour], [components minute], [event.userInfo objectForKey:@"test"]];

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:event.title
message:eventInfo delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}

- (void)weekView:(MAWeekView *)weekView eventDragged:(MAEvent *)event {
NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:event.start];
NSString *eventInfo = [NSString stringWithFormat:@"Event dragged to %02i:%02i. Userinfo: %@", [components hour], [components minute], [event.userInfo objectForKey:@"test"]];

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:event.title
message:eventInfo delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
Expand Down
2 changes: 2 additions & 0 deletions Classes/Views/MAWeekView.h
Expand Up @@ -58,6 +58,7 @@
id<MAWeekViewDelegate> __unsafe_unretained _delegate;
}

@property (readwrite,assign) BOOL eventDraggingEnabled;
@property (readwrite,assign) unsigned int labelFontSize;
@property (nonatomic,copy) NSDate *week;
@property (nonatomic,unsafe_unretained) IBOutlet id<MAWeekViewDataSource> dataSource;
Expand All @@ -78,5 +79,6 @@
@optional
- (void)weekView:(MAWeekView *)weekView eventTapped:(MAEvent *)event;
- (void)weekView:(MAWeekView *)weekView weekDidChange:(NSDate *)week;
- (void)weekView:(MAWeekView *)weekView eventDragged:(MAEvent *)event;

@end
101 changes: 101 additions & 0 deletions Classes/Views/MAWeekView.m
Expand Up @@ -63,6 +63,8 @@ @interface MAEventView : TapDetectingView <TapDetectingViewDelegate> {
CGRect _textRect;
size_t _xOffset;
size_t _yOffset;
CGPoint _touchStart;
BOOL _wasDragged;
}

- (void)setupCustomInitialisation;
Expand Down Expand Up @@ -158,6 +160,7 @@ @implementation MAWeekView

@synthesize labelFontSize=_labelFontSize;
@synthesize delegate=_delegate;
@synthesize eventDraggingEnabled;

- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
Expand All @@ -175,6 +178,7 @@ - (id)initWithCoder:(NSCoder *)decoder {

- (void)setupCustomInitialisation {
self.labelFontSize = DEFAULT_LABEL_FONT_SIZE;
self.eventDraggingEnabled = YES;
self.week = [NSDate date];

[self addSubview:self.topBackground];
Expand Down Expand Up @@ -316,6 +320,7 @@ - (UIScrollView *)scrollView {
_scrollView.backgroundColor = [UIColor whiteColor];
_scrollView.scrollEnabled = TRUE;
_scrollView.alwaysBounceVertical = TRUE;
_scrollView.canCancelContentTouches = NO;
}
return _scrollView;
}
Expand Down Expand Up @@ -823,6 +828,7 @@ - (void)setupCustomInitialisation {
twoFingerTapIsPossible = NO;
multipleTouches = NO;
delegate = self;
self.exclusiveTouch = YES;

self.alpha = kAlpha;
CALayer *layer = [self layer];
Expand Down Expand Up @@ -852,4 +858,99 @@ - (void)tapDetectingView:(TapDetectingView *)view gotSingleTapAtPoint:(CGPoint)t
}
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
_touchStart = [[touches anyObject] locationInView:self];
_wasDragged = NO;
[super touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];

if (!self.weekView.eventDraggingEnabled) {
return;
}

/* No drag & drop for all-day events */
if (_event.allDay) {
return;
}

const CGPoint point = [[touches anyObject] locationInView:self];
CGRect newFrame = CGRectMake(self.frame.origin.x + point.x - _touchStart.x,
self.frame.origin.y + point.y - _touchStart.y,
self.frame.size.width,
self.frame.size.height);

/* Do not allow dragging outside the grid */
const CGPoint topLeft = CGPointMake(CGRectGetMinX(newFrame), CGRectGetMinY(newFrame));
const CGPoint topRight = CGPointMake(CGRectGetMaxX(newFrame), CGRectGetMinY(newFrame));
const CGPoint bottomLeft = CGPointMake(CGRectGetMinX(newFrame), CGRectGetMaxY(newFrame));
const CGPoint bottomRight = CGPointMake(CGRectGetMaxX(newFrame), CGRectGetMaxY(newFrame));

if (![self.weekView.gridView hitTest:topLeft withEvent:event]) {
return;
}
if (![self.weekView.gridView hitTest:topRight withEvent:event]) {
return;
}
if (![self.weekView.gridView hitTest:bottomLeft withEvent:event]) {
return;
}
if (![self.weekView.gridView hitTest:bottomRight withEvent:event]) {
return;
}

self.frame = newFrame;

self.weekView.swipeLeftRecognizer.enabled = NO;
self.weekView.swipeRightRecognizer.enabled = NO;
_wasDragged = YES;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (_wasDragged) {
const double posX = self.frame.origin.x / self.weekView.gridView.cellWidth;
const double posY = self.frame.origin.y / self.weekView.gridView.cellHeight;

/* Align to the grid */
CGRect alignedFrame = CGRectMake(self.weekView.gridView.cellWidth * (int)round(posX),
self.frame.origin.y,
self.frame.size.width,
self.frame.size.height);

self.frame = alignedFrame;

/* Calculate the new time for the event */

const int eventDurationInMinutes = [self.event durationInMinutes];
NSDate *weekday = [self.weekView.weekdayView.weekdays objectAtIndex:(int)round(posX)];
double hours;
double minutes;
minutes = modf(posY, &hours) * 60;

NSDateComponents *startComponents = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:weekday];
[startComponents setHour:(int)hours];
[startComponents setMinute:(int)minutes];
[startComponents setSecond:0];

self.event.start = [CURRENT_CALENDAR dateFromComponents:startComponents];
self.event.end = [self.event.start dateByAddingTimeInterval:eventDurationInMinutes * 60];

self.weekView.swipeLeftRecognizer.enabled = YES;
self.weekView.swipeRightRecognizer.enabled = YES;

if ([self.weekView.delegate respondsToSelector:@selector(weekView:eventDragged:)]) {
[self.weekView.delegate weekView:self.weekView eventDragged:self.event];
}

return;
}

[super touchesEnded:touches withEvent:event];
}

@end

0 comments on commit 34621d6

Please sign in to comment.