Я думаю, что проблема может заключаться в том, что вы сравниваете ширину изображения с высотой, но не учитываете соотношение сторон для imageView.
Это расширение CGSize
для расчета размера aspectFit
или aspectFill
на основе размера «источника» (размера изображения) и размера «цели» (размера imageView).
extension CGSize {
func aspectFit(sourceSize: CGSize, targetSize: CGSize) -> CGSize {
let vWidth = targetSize.width / sourceSize.width;
let vHeight = targetSize.height / sourceSize.height;
var returnSize = targetSize
if( vHeight < vWidth ) {
returnSize.width = targetSize.height / sourceSize.height * sourceSize.width;
}
else if( vWidth < vHeight ) {
returnSize.height = targetSize.width / sourceSize.width * sourceSize.height;
}
return returnSize;
}
func aspectFill(sourceSize: CGSize, targetSize: CGSize) -> CGSize {
let vWidth = targetSize.width / sourceSize.width;
let vHeight = targetSize.height / sourceSize.height;
var returnSize = targetSize
if( vHeight > vWidth ) {
returnSize.width = targetSize.height / sourceSize.height * sourceSize.width;
}
else if( vWidth > vHeight ) {
returnSize.height = targetSize.width / sourceSize.width * sourceSize.height;
}
return returnSize;
}
}
Для вашего случая вы хотите получить размер aspectFill
.
Вот простой, полный пример, который сравнивает результаты ваших исходных расчетов с вычислением aspectFill
. Я использовал размеры изображений, которые вы добавили в свой вопрос, и размер изображения imageView 375 x 667
(в полноэкранном режиме на iPhone 7):
extension CGSize {
func aspectFit(sourceSize: CGSize, targetSize: CGSize) -> CGSize {
let vWidth = targetSize.width / sourceSize.width;
let vHeight = targetSize.height / sourceSize.height;
var returnSize = targetSize
if( vHeight < vWidth ) {
returnSize.width = targetSize.height / sourceSize.height * sourceSize.width;
}
else if( vWidth < vHeight ) {
returnSize.height = targetSize.width / sourceSize.width * sourceSize.height;
}
return returnSize;
}
func aspectFill(sourceSize: CGSize, targetSize: CGSize) -> CGSize {
let vWidth = targetSize.width / sourceSize.width;
let vHeight = targetSize.height / sourceSize.height;
var returnSize = targetSize
if( vHeight > vWidth ) {
returnSize.width = targetSize.height / sourceSize.height * sourceSize.width;
}
else if( vWidth > vHeight ) {
returnSize.height = targetSize.width / sourceSize.width * sourceSize.height;
}
return returnSize;
}
}
class TestViewController: UIViewController {
let testSizes: [CGSize] = [
// width > height
CGSize(width: 2715.0, height: 1920.0),
CGSize(width: 1945.0, height: 1920.0),
CGSize(width: 2278.0, height: 1920.0),
// used to provide a blank line in debug output
CGSize.zero,
// height > width
CGSize(width: 1080.0, height: 2280.0),
CGSize(width: 1080.0, height: 2160.0),
CGSize(width: 1083.0, height: 1920.0),
CGSize(width: 1080.0, height: 2160.0),
// used to provide a blank line in debug output
CGSize.zero,
// height > width problems
CGSize(width: 1300.0, height: 1920.0),
CGSize(width: 1143.0, height: 1920.0),
CGSize(width: 1281.0, height: 1920.0),
]
let imageViewSize = CGSize(width: 375, height: 667)
override func viewDidLoad() {
super.viewDidLoad()
print()
testSizes.forEach { sz in
if sz == CGSize.zero {
print()
} else {
// original size calcs
if sz.height > sz.width {
let newSZ = scaleImageWidth(sourceImageSize: sz, scaledToWidth: imageViewSize.width)
print("Orig: \(newSZ)")
} else {
let newSZ = scaleImageHeight(sourceImageSize: sz, scaledToHeight: imageViewSize.height)
print("Orig: \(newSZ)")
}
// aspectFill calc
let newSZ = sz.aspectFill(sourceSize: sz, targetSize: imageViewSize)
print("Fill: \(newSZ)")
}
}
print()
}
func scaleImageWidth(sourceImageSize: CGSize, scaledToWidth: CGFloat) -> CGSize {
let oldWidth = sourceImageSize.width
let scaleFactor = scaledToWidth / oldWidth
let newHeight = sourceImageSize.height * scaleFactor
let newWidth = oldWidth * scaleFactor
return CGSize(width: newWidth, height: newHeight)
}
func scaleImageHeight(sourceImageSize: CGSize, scaledToHeight: CGFloat) -> CGSize {
let oldheight: CGFloat = sourceImageSize.height
let scaleFactor: CGFloat = scaledToHeight / oldheight
let newWidth: CGFloat = sourceImageSize.width * scaleFactor
let newHeight: CGFloat = oldheight * scaleFactor
return CGSize(width: newWidth, height: newHeight)
}
}
Вот что вы должны получить в консоли отладки:
Orig: (943.1796875, 667.0)
Fill: (943.1796875, 667.0)
Orig: (675.6848958333334, 667.0)
Fill: (675.6848958333334, 667.0)
Orig: (791.3677083333333, 667.0)
Fill: (791.3677083333333, 667.0)
Orig: (375.0, 791.6666666666666)
Fill: (375.0, 791.6666666666666)
Orig: (375.0, 750.0)
Fill: (375.0, 750.0)
Orig: (375.0, 664.819944598338)
Fill: (376.2296875, 667.0)
Orig: (375.0, 750.0)
Fill: (375.0, 750.0)
Orig: (374.99999999999994, 553.8461538461538)
Fill: (451.61458333333337, 667.0)
Orig: (375.0, 629.9212598425197)
Fill: (397.0734375, 667.0)
Orig: (375.0, 562.0608899297424)
Fill: (445.0140625, 667.0)
Как вы можете видеть, "проблемные" размеры, которые вы разместили, имеют отчетливо разные размеры возврата.