Отговорът е лесен. Кодът проработи. Той добави заоблени ъгли към обекта UIImageView и maskToBounds работи добре.
Но действителното показано изображение е по-малко. Използвах AspectFit като режим, за да гарантирам, че действителното изображение не се притиска, а се показва в оригиналното си съотношение на аспектите. Поради по-дългото оформление на размерите на iPhone5 изображението запълваше само част от собствения UIImageView. Промених цвета на фона на сив за екранната снимка и сега става ясно.
Така че решението ще бъде, че ще трябва да изчисля правилния размер на изгледа на изображението, така че да съответства точно на размера на мащабираното изображение. След това трябва да работи.
(Ще актуализирам този отговор, когато приключи).
Актуализация: това е, което най-накрая направих: премахнах UIImageView от Storyboard и се справям с него програмно.
Не се обърквайте от сложността. Добавих друг изглед само за да хвърля сянка, въпреки че това не е свързано с първоначалния въпрос. Сянката, която така или иначе исках да добавя. И се оказа, че сянката на CALayer и masksToBounds=YES
всъщност не са съгласни. Ето защо добавих обикновен UIView, който се намира между изгледа на картата и изгледа на фона.
И накрая, това е толкова неприятно за показване на просто правоъгълно изображение, че мисля, че просто подкласиране на UIView и изчертаване на всичко с openGL или така директно в CALayer вероятно би било много по-лесно. :-)
Както и да е, това е моят код:
- (void)viewDidLoad {
[super viewDidLoad];
self.state = @0;
// Create an image view to carry the image with round rects
// and create a regular view to create the shadow.
// Add the shadow view first so that it appears behind
// the actual image view.
// Explanation: We need a separate view for the shadow with the same
// dimenstions as the imageView. This is because the imageView's image
// is rectangular and will only be clipped to round rects when the
// property masksToBounds is set to YES. But this setting will also
// clip away any shadow that the imageView's layer may have.
// Therfore we add a separate mainly empty UIView just behind the
// UIImageview to throw the shadow.
self.shadowV = [[UIView alloc] init];
self.imageV = [[UIImageView alloc] initWithImage:self.image];
[self.view addSubview:self.shadowV];
[self.shadowV addSubview:self.imageV];
// set the raidus and the mask to follow the rounded corners.
[self.imageV.layer setCornerRadius:CORNER_RADIUS];
[self.imageV.layer setMasksToBounds:YES];
[self.imageV setContentMode:UIViewContentModeScaleAspectFit];
// set the shadows properties
[self.shadowV.layer setShadowColor:[UIColor blackColor].CGColor];
[self.shadowV.layer setShadowOpacity:0.4];
[self.shadowV.layer setShadowRadius:3.0];
[self.shadowV.layer setShadowOffset:CGSizeMake(SHADOW_OFFSET, SHADOW_OFFSET)];
[self.shadowV.layer setCornerRadius:CORNER_RADIUS];
[self.shadowV setBackgroundColor:[UIColor whiteColor]]; // The view needs to have some content. Otherwise it is not displayed at all, not even its shadow.
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Just to be save
if (!self.image) {
return;
}
self.imageV.image = self.image; // The image property was set by the caller.
// Layout imageV within self.view with a margin of MARGIN
self.imageV.frame = CGRectMake(MARGIN, MARGIN, self.view.bounds.size.width - 2 * MARGIN, self.view.bounds.size.height - 2 * MARGIN);
// Calculate the size and position of the image and set the image view to
// the same dimensions
// This works under the assumption, that the image content mode is aspectFit.
// Well, as we are doing so much of the layout manually, it would work with a number of content modes. :-)
float imageWidth, imageHeight;
float heightWidthRatioImageView = self.view.frame.size.height / self.view.frame.size.width;
float heightWidthRatioImage = self.image.size.height / self.image.size.width;
if (heightWidthRatioImageView > heightWidthRatioImage) {
// The ImageView is "higher" than the image itself.
// --> The image width is set to the imageView width and its height is scaled accordingly.
imageWidth = self.imageV.frame.size.width;
imageHeight = imageWidth * heightWidthRatioImage;
} else {
// The ImageView is "wider" than the image itself.
// --> The image height is set to the imageView height and its width is scaled accordingly.
imageHeight = self.imageV.frame.size.height;
imageWidth = imageHeight / heightWidthRatioImage;
}
// Layout imageView and ShadowView accordingly.
CGRect imageRect =CGRectMake((self.view.bounds.size.width - imageWidth) / 2,
(self.view.bounds.size.height - imageHeight) / 2,
imageWidth, imageHeight);
[self.shadowV setFrame:imageRect];
[self.imageV setFrame:CGRectMake(0.0f, 0.0f, imageWidth, imageHeight)]; // Origin is (0,0) because it overlaps its superview which just throws the shadow.
}
И ето как изглежда най-накрая:
person
Hermann Klecker
schedule
30.03.2014
frame
, трябва да кажетеbounds
- рамката на изгледа на изображението е позиционирана спрямо границите наself.view
, а не неговата рамка. - person matt   schedule 30.03.2014