blob: d11274c0929e0021fab3464e2d8a8ca1f5e2e64e [file]
// Copyright 2017-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#import "MDCSheetBehavior.h"
/**
These values were arrived at empirically (through trial and error) to either emphasize or diminish
the bounce effect that UIKit dynamics provides.
*/
static const CGFloat kSimulateScrollViewBounceFrequency = 3.5f;
static const CGFloat kSimulateScrollViewBounceDamping = 0.4f;
static const CGFloat kDisableScrollViewBounceFrequency = 5.5f;
static const CGFloat kDisableScrollViewBounceDamping = 1.0f;
@interface MDCSheetBehavior ()
@property(nonatomic) UIAttachmentBehavior *attachmentBehavior;
@property(nonatomic) UIDynamicItemBehavior *itemBehavior;
@property(nonatomic) id<UIDynamicItem> item;
@end
@implementation MDCSheetBehavior
- (instancetype)initWithItem:(id<UIDynamicItem>)item
simulateScrollViewBounce:(BOOL)simulateScrollViewBounce {
self = [super init];
if (self) {
_item = item;
_attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self.item
attachedToAnchor:CGPointZero];
if (simulateScrollViewBounce) {
_attachmentBehavior.frequency = kSimulateScrollViewBounceFrequency;
_attachmentBehavior.damping = kSimulateScrollViewBounceDamping;
} else {
_attachmentBehavior.frequency = kDisableScrollViewBounceFrequency;
_attachmentBehavior.damping = kDisableScrollViewBounceDamping;
}
_attachmentBehavior.length = 0;
// Anchor movement along the y-axis.
__weak MDCSheetBehavior *weakSelf = self;
_attachmentBehavior.action = ^{
MDCSheetBehavior *strongSelf = weakSelf;
CGPoint center = item.center;
center.x = strongSelf->_targetPoint.x;
item.center = center;
};
[self addChildBehavior:_attachmentBehavior];
_itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[ self.item ]];
_itemBehavior.density = 100;
_itemBehavior.resistance = 10;
[self addChildBehavior:_itemBehavior];
}
return self;
}
- (void)setTargetPoint:(CGPoint)targetPoint {
_targetPoint = targetPoint;
self.attachmentBehavior.anchorPoint = targetPoint;
}
- (void)setVelocity:(CGPoint)velocity {
_velocity = velocity;
CGPoint currentVelocity = [self.itemBehavior linearVelocityForItem:self.item];
CGPoint velocityDelta =
CGPointMake(velocity.x - currentVelocity.x, velocity.y - currentVelocity.y);
[self.itemBehavior addLinearVelocity:velocityDelta forItem:self.item];
}
@end