web-dev-qa-db-ja.com

AutoLayoutで画像に一致するようにUIImageViewサイズを変更します

UIImageViewの高さ/幅を、フォトアルバムから選択した画像に合わせて変更したいのですが、ここでスニペットを見つけました。

-(CGRect)frameForImage:(UIImage *)imgs inImageViewAspectFit:(UIImageView *)imagev
{
  float imageRatio = imgs.size.width / imgs.size.height;
  float viewRatio = imagev.frame.size.width / imagev.frame.size.height;
  if(imageRatio < viewRatio)
  {
    float scale = imagev.frame.size.height / imgs.size.height;
    float width = scale * imgs.size.width;
    float topLeftX = (imagev.frame.size.width - width) * 0.5;
    NSLog(@"image after aspect fit: width=%f",width);
    imagev.frame = CGRectMake(topLeftX, 0, width, imagev.frame.size.height);
    return CGRectMake(topLeftX, 0, width, imagev.frame.size.height);
  }
  else
  {
    float scale = imagev.frame.size.width / imgs.size.width;
    float height = scale * imgs.size.height;
    float topLeftY = (imagev.frame.size.height - height) * 0.5;
    NSLog(@"image after aspect fit: height=%f", height);
    imagev.frame = CGRectMake(0, topLeftY, imagev.frame.size.width, height);
    return CGRectMake(0, topLeftY, imagev.frame.size.width, height);
  }
}

問題は、ボタンから呼び出すとUIImageViewの高さ/幅が変わることです

- (IBAction)changeSize:(id)sender
{
  [self frameForImage:image inImageViewAspectFit:self.imageView];    
}

しかし、フォトアルバムから画像を選択したらすぐにそれを実行したいと思います。これが設定方法です。

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
  image = [info objectForKey:UIImagePickerControllerOriginalImage];
  [self.imageView setImage:image];
  [self frameForImage:image inImageViewAspectFit:self.imageView];
  [self dismissViewControllerAnimated:YES completion:NULL];
}
18
Mike Tyson

自動レイアウトソリューション

プロジェクトで自動レイアウトを使用していることを確認してから、画像ビューの画像を変更し、高さを調整する方法を示すデモアプリを作成しました。自動レイアウトはこれを自動的に行いますが、キャッチするのは、使用する写真がユーザーギャラリーから来ているため、非常に大きくなる可能性が高いことです。

アプリをチェックしてください: https://bitbucket.org/danielphillips/auto-layout-imageview

トリックは、画像ビューの高さのNSLayoutConstraintの参照を作成することです。画像を変更するときは、一定の幅が与えられると、正しい高さに定数を調整する必要があります。

他の解決策は、contentModeを使用して画像ビューにUIViewContentModeScaleAspectFitを設定することです。画像は常に完全に表示されますが、画像ビューの境界にロックされます。あなたが持っている自動レイアウト制約で。

最初の返信

私が何かを見逃していない限り、あなたは本当にこれを複雑にしています。

画像ピッカーから新しい画像を取得する際に必要なことは、UIImageサイズに従って画像ビューのフレームを変更することだけです。

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
  image = [info objectForKey:UIImagePickerControllerOriginalImage];
  [self.imageView setImage:image];
  self.imageView.frame = CGRectMake(self.imageView.frame.Origin.x
                                    self.imageView.frame.Origin.y
                                    image.size.width
                                    image.size.height);
  [self dismissViewControllerAnimated:YES completion:NULL];
}

もちろん、これは潜在的に非常に大きくなります(非常に大きくなる可能性のある元の画像を使用しています)。

幅を280ポイントにロックしましょう。こうすることで、常にポートレートモードで画面全体を表示できます。

したがって、画像サイズが1000x800で、画像ビューがおそらく280x100であると仮定します。次のように、画像ビューの幅を保持したまま画像ビューの正しい高さを計算できます。

CGSize imageSize        = CGSizeMake(1000.0, 800.0);
CGSize imageViewSize    = CGSizeMake(280.0, 100.0);

CGFloat correctImageViewHeight = (imageViewSize.width / imageSize.width) * imageSize.height;

self.imageView.frame = CGRectMake(  self.imageView.frame.Origin.x,
                                    self.imageView.frame.Origin.x,
                                    CGRectGetWidth(self.imageView.bounds),
                                    correctImageViewHeight);
32
Daniel

選択した幅または高さの制限に基づいて画像の正しいサイズを返すのに役立つSwiftクラスです:

class func returnImageSizeForHeightLimit(heightLimit:CGFloat?, orWidthLimit widthLimit:CGFloat?, forImage theImage:UIImage)->CGSize?{

    if let myHeightLimit = heightLimit {

        let theWidth = (myHeightLimit/theImage.size.height) * theImage.size.width

        return CGSizeMake(theWidth, myHeightLimit)
    }

    if let myWidthLimit = widthLimit {

        let theHeight = (myWidthLimit/theImage.size.width) * theImage.size.height

        return CGSizeMake(myWidthLimit, theHeight)
    }

    return nil
}
5
PJeremyMalouf