我有一个UIImagePicker适用于某种类型的UIImagePickerControllerSourceTypePhotoLibrary,但是当我使用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) {
}];
}
}
正如您所看到的,我显示它们完全相同,但相机编辑的行为与照片库编辑不同。
答案 0 :(得分:50)
看起来这种行为只是iOS 6中的一个错误...基本上你无法移动编辑框,除非你放大一点,它总是会反弹到中间。希望他们很快能解决这个问题。
答案 1 :(得分:2)
谢谢yycking。这 extension 有效。除了我在 viewDidLayoutSubviews
中添加了方法调用,这样我就不必每次打开图像选择器时都调用它。
这是完整的扩展
extension UIImagePickerController {
open override var childForStatusBarHidden: UIViewController? {
return nil
}
open override var prefersStatusBarHidden: Bool {
return true
}
open override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
fixCannotMoveEditingBox()
}
func fixCannotMoveEditingBox() {
if let cropView = cropView,
let scrollView = scrollView,
scrollView.contentOffset.y == 0 {
var top: CGFloat = 0.0
if #available(iOS 11.0, *) {
top = cropView.frame.minY + self.view.safeAreaInsets.top
} else {
// Fallback on earlier versions
top = cropView.frame.minY
}
let bottom = scrollView.frame.height - cropView.frame.height - top
scrollView.contentInset = UIEdgeInsets(top: top, left: 0, bottom: bottom, right: 0)
var offset: CGFloat = 0
if scrollView.contentSize.height > scrollView.contentSize.width {
offset = 0.5 * (scrollView.contentSize.height - scrollView.contentSize.width)
}
scrollView.contentOffset = CGPoint(x: 0, y: -top + offset)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
self?.fixCannotMoveEditingBox()
}
}
var cropView: UIView? {
return findCropView(from: self.view)
}
var scrollView: UIScrollView? {
return findScrollView(from: self.view)
}
func findCropView(from view: UIView) -> UIView? {
let width = UIScreen.main.bounds.width
let size = view.bounds.size
if width == size.height, width == size.height {
return view
}
for view in view.subviews {
if let cropView = findCropView(from: view) {
return cropView
}
}
return nil
}
func findScrollView(from view: UIView) -> UIScrollView? {
if let scrollView = view as? UIScrollView {
return scrollView
}
for view in view.subviews {
if let scrollView = findScrollView(from: view) {
return scrollView
}
}
return nil
}
}
答案 2 :(得分:0)
这是Image Picker Controller的默认行为,您无法更改它。唯一的另一种选择是创建自己的裁剪实用程序。请查看以下链接以获取示例:
答案 3 :(得分:0)
如果已在info.plist中将“基于视图控制器的状态栏外观”设置为“否”,并使用来将状态栏外观设置为浅色
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
})}
显然,这是解决该问题的方法。希望这会有所帮助。
答案 4 :(得分:-1)
解决此问题的解决方法是在info.plist中添加一个条目,其中“基于控制器的状态栏状态栏外观”设置为NO
答案 5 :(得分:-1)
愚蠢的答案
重置contentInset的滚动视图
<h2>OUTSIDE MAT FORM FIELD</h2>
<app-state-selector
name="people2"
[ngModel]="peopleList2"
#peopleRef2="ngModel"
required
maxlength=5
></app-state-selector>
<div class="matFormFieldUnderline" [style.background-color]="peopleRef2.errors ? 'red' : null"></div>
<div fxLayout>
<div fxFlex="70">
<mat-hint *ngIf="!peopleRef2.errors?.rows">Valid component: {{ peopleRef2.valid }}</mat-hint>
<mat-error *ngIf="peopleRef2.errors?.rows">Valid component: {{ peopleRef2.valid }}</mat-error>
</div>
<div fxFlex="30" fxLayoutAlign="end">
<mat-hint>{{peopleRef2.value?.length || 0}} rows</mat-hint>
</div>
</div>
<mat-error *ngIf="peopleRef2.errors?.required">required</mat-error>
<mat-error *ngIf="peopleRef2.errors?.maxlength">max 5 rows</mat-error>
然后称呼
#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