我的一位客户让我用两张照片制作合成图像。他们希望将选定的图像排成一行并创建一个新的大图像。
我为每个图像使用UIImageView并将图像设置为它的图像属性。然后使用CGContext创建一个新的排列图像并获得一个新的UIImage。
当我使用iPad拍摄的照片时,它工作正常,我可以将新的图像保存到照片中。
但是当我尝试使用两个创建的大图像时,它在尝试使用两个图像执行segue时崩溃,并导致iPad重新启动。
我得到了以下的错误。
2016-04-24 13:51:30.607 Kiss2-test[2664:3832804] XPC connection interrupted
2016-04-24 13:51:30.764 Kiss2-test[2664:3832514] Terminating since there is no system app.
我发现这些错误发生在segue.nextView上。 nextView显示在两个不同的ViewControllers中。不同的是,一个只发送一个UIImage,而另一个发送两个UIImage。就我而言,它发生在第二个。
这两张照片的宽度和高度都是未知的,直到nextView得到它们。所以在
- (void)viewDidLayoutSubviews {}
我在下面写了代码。
firstImage = _argImage1; // setting the first original UIImage to another UIImage
secondImage = _argImage2; // setting the second original UIImage to another UIImage
// _placeHolder is a UIView wchich top is below navigation bar and bottom is above toolbar.
// This method is viewDidLayoutSubviews, so may be called several times.
// to avoid multiple constraints for the same view, remove them from _placeHolder
[_placeHolder removeConstraints:arrayLeftPlaceHolderConstraints];
[_placeHolder removeConstraints:arrayRightPlaceHolderConstraints];
[_placeHolder removeConstraints:aryCanvasViewConstraints];
// Canvas image will be added to _placeHolder to cover two images and
// let users draw images over photos.
expectedCanvasImageSize = CGSizeMake((firstImage.size.width + secondImage.size.width), (firstImage.size.height > secondImage.size.height)?firstImage.size.height:secondImage.size.height);
// Add two image's width to know the total width.
CGFloat summaryOfImageWidth = firstImage.size.width + secondImage.size.width;
// Get the ratio from each image.size.width devided by summaryOfImageWidth, so I can
// get the each UIImageView's widths.
CGFloat leftImageRatio = firstImage.size.width / summaryOfImageWidth;
CGFloat rightImageRatio = secondImage.size.width / summaryOfImageWidth;
// Get the both UIImageViews' width in _placeHokder.
leftImageWidth = _placeHolder.frame.size.width * leftImageRatio;
rightImageWidth = _placeHolder.frame.size.width * rightImageRatio;
// Prepare left side placeHolder.
if(!leftPlaceHolder) {
leftPlaceHolder = [UIView new];
[_placeHolder addSubview:leftPlaceHolder];
}
// Prepare right side placeHolder.
if(!rightPlaceHolder) {
rightPlaceHolder = [UIView new];
[_placeHolder addSubview:rightPlaceHolder];
}
// add constraints for both new placeholders.
// Left
// Set the left side to _placeHolder's left.
leftPlaceHolder.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *leftPlaceHolderXConstraint =
[NSLayoutConstraint constraintWithItem:leftPlaceHolder
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:_placeHolder
attribute:NSLayoutAttributeLeft
multiplier:1
constant:0];
// Vertically center in _placeHolder
NSLayoutConstraint *leftPlaceHolderViewYConstraint =
[NSLayoutConstraint constraintWithItem:leftPlaceHolder
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:_placeHolder
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0];
// set Width
NSLayoutConstraint *leftPlaceHolderWidthConstraint =
[NSLayoutConstraint constraintWithItem:leftPlaceHolder
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:leftImageWidth];
// set Height
NSLayoutConstraint *leftPlaceHolderHeightConstraint =
[NSLayoutConstraint constraintWithItem:leftPlaceHolder
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:_placeHolder
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:0];
// creating an array of constraints and add the array to _placeGolder constraints
arrayLeftPlaceHolderConstraints = @[leftPlaceHolderXConstraint, leftPlaceHolderViewYConstraint, leftPlaceHolderWidthConstraint, leftPlaceHolderHeightConstraint];
[_placeHolder addConstraints:arrayLeftPlaceHolderConstraints];
// right
// Set the right side to _placeHolder's right.
rightPlaceHolder.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *rightPlaceHolderXConstraint =
[NSLayoutConstraint constraintWithItem:rightPlaceHolder
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:_placeHolder
attribute:NSLayoutAttributeRight
multiplier:1
constant:0];
// Vertically center in _placeHolder
NSLayoutConstraint *rightPlaceHolderViewYConstraint =
[NSLayoutConstraint constraintWithItem:rightPlaceHolder
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:_placeHolder
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0];
// set Width
NSLayoutConstraint *rightPlaceHolderWidthConstraint =
[NSLayoutConstraint constraintWithItem:rightPlaceHolder
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:rightImageWidth];
// et Height
NSLayoutConstraint *rightPlaceHolderHeightConstraint =
[NSLayoutConstraint constraintWithItem:rightPlaceHolder
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:_placeHolder
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:0];
arrayRightPlaceHolderConstraints = @[rightPlaceHolderXConstraint, rightPlaceHolderViewYConstraint, rightPlaceHolderWidthConstraint, rightPlaceHolderHeightConstraint];
[_placeHolder addConstraints:arrayRightPlaceHolderConstraints];
// Creating CGRect for left placeHolder
leftRect = CGRectMake(0, 0, leftImageWidth,_placeHolder.frame.size.height);
// Creating CGRect for right placeHolder
rightRect = CGRectMake(leftImageWidth, 0, rightImageWidth, _placeHolder.frame.size.height);
// Get the image size to show using calcurateImageSize class.
// This initialization will prepare calcuration for size of firstImage to show in the leftRect.
imageSizeCalcurator = [[calcurateImageSize alloc]initWithBackGroundFrame:leftRect withImage:firstImage];
// Get the image size to show.
showingSize1 = [imageSizeCalcurator calcSingleImageMaximumSize];
imageSizeCalcurator = nil;
This initialization will prepare calcuration for size of secondImage to show in the rightRect.
imageSizeCalcurator = [[calcurateImageSize alloc]initWithBackGroundFrame:rightRect withImage:secondImage];
// Get the image size to show.
showingSize1 = [imageSizeCalcurator calcSingleImageMaximumSize];
showingSize2 = [imageSizeCalcurator calcSingleImageMaximumSize];
// Getting the expected size which will cover both two images shown.
CGFloat imageViewWidth = showingSize1.width + showingSize2.width;
CGFloat imageViewHeight = (showingSize1.height > showingSize2.height)?showingSize1.height:showingSize2.height;
// Creating new UIImageView in _placeHolder for two images.
if(!oneImageView) {
oneImageView = [UIImageView new];
[_placeHolder addSubview:oneImageView];
}
// Add constraints for new UIImageBiew
// Holizontally Center
oneImageView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *oneImageViewXConstraint =
[NSLayoutConstraint constraintWithItem:oneImageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:_placeHolder
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0];
// Vertically Center
NSLayoutConstraint *oneImageViewViewYConstraint =
[NSLayoutConstraint constraintWithItem:oneImageView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:_placeHolder
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0];
// set Width
NSLayoutConstraint *oneImageViewWidthConstraint =
[NSLayoutConstraint constraintWithItem:oneImageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:imageViewWidth];
// set Height
NSLayoutConstraint *oneImageViewHeightConstraint =
[NSLayoutConstraint constraintWithItem:oneImageView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:imageViewHeight];
NSArray *arrayOneImageConstraints = @[oneImageViewXConstraint, oneImageViewViewYConstraint, oneImageViewWidthConstraint, oneImageViewHeightConstraint];
[_placeHolder addConstraints:arrayOneImageConstraints];
// Image Sizes and Positions to draw in context
CGSize firstSize = firstImage.size;
CGSize secondSize = secondImage.size;
CGFloat firstYPos = (firstSize.height > secondSize.height)?0:(secondSize.height - firstSize.height) / 2;
CGFloat secondYPos = (secondSize.height > firstSize.height)?0:(firstSize.height - secondSize.height) / 2;
// CGRect to draw pictures.
CGRect firstRect = CGRectMake(0, firstYPos, firstSize.width, firstSize.height);
CGRect secondRect = CGRectMake(firstSize.width, secondYPos, secondSize.width, secondSize.height);
// Creating CGContext
UIGraphicsBeginImageContextWithOptions(expectedCanvasImageSize, NO, 0.0f);
// draw each image in the CGRect calcurated above.
[firstImage drawInRect:firstRect];
[secondImage drawInRect:secondRect];
// Gettomg composited UIImage Viedw
compositedImage = UIGraphicsGetImageFromCurrentImageContext();
// Ends CGContext image.
UIGraphicsEndImageContext();
oneImageView.image = compositedImage;
// Creating a canvas Image Vew to let the user can draw abouve images.
if(!canvasImageView) {
canvasImageView = [UIImageView new];
canvasImageView.contentMode = UIViewContentModeScaleAspectFit;
[_placeHolder addSubview:canvasImageView];
canvasImageView.translatesAutoresizingMaskIntoConstraints = NO;
canvasImageView.image = nil;
}
if(drawImageBeforeSegue) {
canvasImageView.image = drawImageBeforeSegue;
}
// Determine CanvasView's constraints
// Horizontally Center
NSLayoutConstraint *canvasViewCenterXConstraint =
[NSLayoutConstraint constraintWithItem:canvasImageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:_placeHolder
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0];
// Verticaly Center
NSLayoutConstraint *canvasViewCenterYConstraint =
[NSLayoutConstraint constraintWithItem:canvasImageView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:_placeHolder
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0];
// set the Width
NSLayoutConstraint *canvasViewCenterWidthConstraint =
[NSLayoutConstraint constraintWithItem:canvasImageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:imageViewWidth];
// set the Height
NSLayoutConstraint *canvasViewCenterHeightConstraint =
[NSLayoutConstraint constraintWithItem:canvasImageView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:imageViewHeight];
aryCanvasViewConstraints = @[canvasViewCenterXConstraint, canvasViewCenterYConstraint, canvasViewCenterWidthConstraint, canvasViewCenterHeightConstraint];
[_placeHolder addConstraints:aryCanvasViewConstraints];
由于上面的代码是用viewDidLayoutSubviews编写的,所以首先,我删除了约束。