我有一个类型UIImagePickerControllerSourceTypePhotoLibrary作品完美一UIImagePicker,但是当我使用UIImagePickerControllerSourceTypeCamera,编辑框不能从图像的中心移动。 因此,如果图像是说长得比它宽,用户无法编辑框移动到图像的顶部方形。
任何人都知道为什么会这样呢? 它只有当源是从相机,而不是库发生。
编辑:一些代码!
if (actionSheet.tag == 2) {
if (buttonIndex == 0) { // Camera
// Check for camera
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == YES) {
// Create image picker controller
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.allowsEditing = YES;
// Delegate is self
imagePicker.delegate = self;
// Show image picker
[self presentViewController:imagePicker
animated:YES
completion:^(void) {
}];
}
}
else if (buttonIndex == 1) { // Photo Library
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] == YES) {
// Create image picker controller
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.allowsEditing = YES;
// Delegate is self
imagePicker.delegate = self;
// Show image picker
[self presentViewController:imagePicker
animated:YES
completion:^(void) {
}];
}
}
所以你可以看到,我展示他们完全一样的,但相机编辑的作用比照片库编辑不同。
看起来这种行为只是在iOS 6中的一个错误......基本上你不能移动的编辑框,它总是除非你有点放大反弹到中间。 希望他们很快修复。
这是默认行为的图片选择器控制器,你不能改变它。 唯一的其他选择是创建自己的裁剪工具。 看看下面的一个例子的链接:
https://github.com/ardalahmet/SSPhotoCropperViewController
我知道,这不是一个很好的解决方案,但它的工作原理。
我在iOS8上的iPhone5 +,iOS9 + iPhone6sPlus,iOS10 + iPhone6,iOS10 + iPhone6sPlus测试。
注意 : PLImageScrollView
和PLCropOverlayCropView
是未记录的类。
- (void)showImagePickerControllerWithSourceType:(UIImagePickerControllerSourceType)sourceType {
UIImagePickerController *imagePickerController = [UIImagePickerController new];
imagePickerController.sourceType = sourceType;
imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
imagePickerController.allowsEditing = YES;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:^{
[self fxxxImagePickerController:imagePickerController];
}];
}
- (void)fxxxImagePickerController:(UIImagePickerController *)imagePickerController {
if (!imagePickerController
|| !imagePickerController.allowsEditing
|| imagePickerController.sourceType != UIImagePickerControllerSourceTypeCamera) {
return;
}
// !!!: UNDOCUMENTED CLASS
Class ScrollViewClass = NSClassFromString(@"PLImageScrollView");
Class CropViewClass = NSClassFromString(@"PLCropOverlayCropView");
[imagePickerController.view eachSubview:^BOOL(UIView *subview, NSInteger depth) {
if ([subview isKindOfClass:CropViewClass]) {
// 0. crop rect position
subview.frame = subview.superview.bounds;
}
else if ([subview isKindOfClass:[UIScrollView class]]
&& [subview isKindOfClass:ScrollViewClass]) {
BOOL isNewImageScrollView = !self->_imageScrollView;
self->_imageScrollView = (UIScrollView *)subview;
// 1. enable scrolling
CGSize size = self->_imageScrollView.frame.size;
CGFloat inset = ABS(size.width - size.height) / 2;
self->_imageScrollView.contentInset = UIEdgeInsetsMake(inset, 0, inset, 0);
// 2. centering image by default
if (isNewImageScrollView) {
CGSize contentSize = self->_imageScrollView.contentSize;
if (contentSize.height > contentSize.width) {
CGFloat offset = round((contentSize.height - contentSize.width) / 2 - inset);
self->_imageScrollView.contentOffset = CGPointMake(self->_imageScrollView.contentOffset.x, offset);
}
}
}
return YES;
}];
// prevent re-layout, maybe not necessary
@weakify(self, imagePickerController);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@strongify(self, imagePickerController);
[self fxxxImagePickerController:imagePickerController];
});
}
编辑 : eachSubview:
方法遍历所有的子视图树。
如果您在info.plist中设置“查看基于控制器的状态栏外观” NO和使用设置状态栏外观光
UIApplication.shared.statusBarStyle = .lightContent
或使用任何其他的方法,然后,只需呈现所述图像拾取器之前设置风格.DEFAULT。 对于例如:
imagePicker.allowsEditing = true
imagePicker.sourceType = .photoLibrary
UIApplication.shared.statusBarStyle = .default
present(imagePicker, animated: true, completion: nil)
根据您的需要或作为photoLibrary或相机 ,在你didFinishPickingMediaWithInfo完成块添加以下完成块更改源类型。
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
//let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage
var pickedImage : UIImage?
if let img = info[UIImagePickerControllerEditedImage] as? UIImage
{
pickedImage = img
}
else if let img = info[UIImagePickerControllerOriginalImage] as? UIImage
{
pickedImage = img
}
dismiss(animated: true, completion: {
UIApplication.shared.statusBarStyle = .lightContent
})}
显然,这是针对same.Hope这有助于解决办法。
这解决了它一个解决办法是用“ 查看基于控制器的状态栏外观 ”添加在info.plist中的条目设置为NO
愚蠢的答案
重置滚动型contentInset
#import <objc/runtime.h>
@interface WeakObjectContainer : NSObject
@property (nonatomic, readonly, weak) id object;
@end
@implementation WeakObjectContainer
- (instancetype) initWithObject:(id)object
{
if (!(self = [super init]))
return nil;
_object = object;
return self;
}
@end
@implementation UIImagePickerController (PLUS)
// MARK: - Create a weak stored property in extension
- (id)weakObjectForKey:(const void*)key {
WeakObjectContainer *container = objc_getAssociatedObject(self, key);
return [container object];
}
- (void)setWeakObject:(id)object forKey:(const void*)key {
WeakObjectContainer *container = [[WeakObjectContainer alloc] initWithObject:object];
objc_setAssociatedObject(self, key, container, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
// MARK: - Create a weak property for scrollView
- (UIScrollView *)scrollView {
return [self weakObjectForKey:_cmd];
}
- (void)setScrollView:(UIScrollView *)scrollView {
[self setWeakObject:scrollView forKey:@selector(scrollView)];
}
// MARK: - Create a weak property for cropView
- (UIView *)cropView {
return [self weakObjectForKey:_cmd];
}
- (void)setCropView:(UIView *)cropView {
[self setWeakObject:cropView forKey:@selector(cropView)];
}
// MARK: - Fix cannot move editing xox
- (void)fixCannotMoveEditingBox {
if (!self.scrollView || !self.cropView) {
UIView *view = [self view];
self.scrollView = [self findScrollView:view];
self.cropView = [self findCropView:view];
if (self.scrollView && self.cropView) {
CGFloat top = self.cropView.frame.origin.y;
CGFloat bottom = ({
self.scrollView.frame.size.height - self.cropView.frame.size.height - self.cropView.frame.origin.y;
});
self.scrollView.contentInset = UIEdgeInsetsMake(top, 0, bottom, 0);
self.scrollView.contentOffset = CGPointMake(0, -1);
}
}
__weak typeof(self) weakself = self;
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
dispatch_after(delay, dispatch_get_main_queue(), ^(void){
__strong typeof(weakself) strongself = weakself;
[strongself fixCannotMoveEditingBox];
});
}
- (UIScrollView *)findScrollView:(UIView *)view {
if ([view isKindOfClass:[UIScrollView class]]) {
return (UIScrollView *)view;
}
for (UIView *subview in [view subviews]) {
UIScrollView *view = [self findScrollView:subview];
if (view) {
return view;
}
}
return nil;
}
- (UIView *)findCropView:(UIView *)view {
CGFloat width = [[UIScreen mainScreen] bounds].size.width;
CGSize size = [view frame].size;
if (size.width == width && size.height == width) {
return view;
}
for (UIView *subview in [view subviews]) {
UIView *view = [self findCropView:subview];
if (view) {
return view;
}
}
return nil;
}
@end
然后调用它
[imagePickerController fixCannotMoveEditingBox];