2016-12-09 2 views
2

Ich muss Profil ImageView für den Chat mit einer bestimmten Anzahl von Mitgliedern zu implementieren.Profil ImageView von mehreren Bildern

Es sollte dieser wie aussehen:

profile image view

So auf die Menge der Mitglieder in Abhängigkeit, Imageview auf geeignete Teile aufgeteilt werden sollte, die entsprechende Fotos von jedem Chat-Mitgliedern bestehen sollte.

upd: Ich fand eine Lösung (siehe unten) und es funktioniert, aber einige Bilder sind gestreckt, weil ihr reales Verhältnis 1: 1 ist. Wie dehnt man UIImage (mit 1: 1-Verhältnis) proportional zur Rechteckgröße?

my ex

class ProfileImageHelper { 

    class func collageImage (rect:CGRect, images:[UIImage]) -> UIImage { 

     let maxImagesPerRow = 2 
     let maxSide = rect.width/CGFloat(maxImagesPerRow) 

     var index = 0 
     var currentRow = 1 
     var xtransform:CGFloat = 0.0 
     let transformOffset:CGFloat = 1.5 

     var ytransform:CGFloat = 0.0 
     var smallRect:CGRect = CGRect.zero 

     UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)//UIScreen.main.scale) 

     for img in images { 

      index += 1 

      let x = index % maxImagesPerRow //row should change when modulus is 0 

      //row changes when modulus of counter returns zero @ maxImagesPerRow 
      if x == 0 { 
       //last column of current row 
       //xtransform += CGFloat(maxSide) 
       smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height/CGFloat(currentRow)) - transformOffset) 

       //reset for new row 
       currentRow += 1 
       xtransform = 0.0 
       ytransform = (maxSide * CGFloat(currentRow - 1)) + transformOffset 

      } else { 
       //not a new row 
       if xtransform == 0 { 
        //this is first column 
        //draw rect at 0,ytransform 
        smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height/CGFloat(currentRow)) - transformOffset) 
        xtransform += CGFloat(maxSide) + transformOffset 
       } else { 
        //not the first column so translate x, ytransform to be reset for new rows only 
        smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height/CGFloat(currentRow)) - transformOffset) 
        xtransform += CGFloat(maxSide) + transformOffset 
       } 
      } 

      //draw in rect 
      img.draw(in: smallRect) 

     } 

     let outputImage = UIGraphicsGetImageFromCurrentImageContext(); 

     UIGraphicsEndImageContext(); 

     return outputImage! 
    } 
} 

Irgendwelche Vorschläge?

+1

die Bilder auf Core Graphics ziehen und zurück als UIImage. – GeneCode

+0

beste Weise, das zu tun, benutzen Sie 3 Bildansicht und in diesem Imageview zeichne es mit breazerpath UIBezierPath für cornerradius für 3 diffent Bild –

+0

Ein UIImageView ist genug. Warum verschwenden Sie die Ressource mit 3 ImageView für solch eine einfache Komponente? – GeneCode

Antwort

0

löste ich meine Frage, dies mit:

class ProfileImageHelper { 

    class func collageImage (size:CGSize, images:[UIImage]) -> UIImage { 

     let maxImagesPerRow = 2 
     let maxSide = size.width/CGFloat(maxImagesPerRow) 

     var index = 0 
     var currentRow = 1 
     var xtransform:CGFloat = 0.0 
     let transformOffset:CGFloat = 0.5 
     var ytransform:CGFloat = 0.0 
     var smallRect:CGRect = CGRect.zero 

     UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) 

     for img in images { 

      index += 1 

      if index == 5 { break } 

      let x = index % maxImagesPerRow //row should change when modulus is 0 

      //row changes when modulus of counter returns zero @ maxImagesPerRow 
      if x == 0 { 
       //last column of current row 
       //get small image for two rows column 
       if Int(images.count/2) > 1 { 
        smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (size.height/2) - transformOffset) 
        img.draw(in: smallRect) 
       //fit image to vertical column 
       } else { 
        smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: size.height) 
        if let newImage = img.cropImageByMiddle() { 
         newImage.draw(in: smallRect) 
        } 
       } 

       //reset for new row 
       currentRow += 1 
       xtransform = 0.0 
       ytransform = (maxSide * CGFloat(currentRow - 1)) + transformOffset 

      } else { 
       //not a new row 
       if xtransform == 0 { 
        //this is first column 
        //draw rect at 0,ytransform 
        if images.count == 2 { 
         smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: size.height) 
         if let newImage = img.cropImageByMiddle() { 
          newImage.draw(in: smallRect) 
         } 
        } else { 
         smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (size.height/2) - transformOffset) 
         img.draw(in: smallRect) 
        } 
        xtransform += CGFloat(maxSide) + transformOffset 
       } 
      } 
     } 

     let outputImage = UIGraphicsGetImageFromCurrentImageContext(); 


     UIGraphicsEndImageContext(); 

     return outputImage! 
    } 
} 

I Ernte Bild, Mittelteil bekommen es zu vertikalen Spalte zu passen. Dafür Ich schrieb Erweiterung für UIImage:

extension UIImage { 
    func cropImageByMiddle() -> UIImage? { 
     let cropRect = CGRect(x: self.size.width/4, y: 0, width: self.size.width/2, height: self.size.height) 
     if let cgImg = self.cgImage { 
      if let new = cgImg.cropping(to: cropRect) { 
       return UIImage(cgImage: new) 
      } 
     } 
     return nil 
    } 
} 
1

Mit dem folgenden Code können Sie ein Bild über einem anderen einfügen. Sie können die x/y-Positionen verwenden, um das Bild entsprechend zu verschieben. Sie können dann das endgültige Bild zu einem Kreis zuschneiden.

UIImage *backrgoundImage = [[UIImage alloc] init]; 
backrgoundImage = image1; 

UIImage *foregroundImage = [[UIImage alloc] init]; 
foregroundImage = image2; 

UIGraphicsBeginImageContextWithOptions(backrgoundImage.size, FALSE, 0.0); 
[backrgoundImage drawInRect:CGRectMake(0, 0, backrgoundImage.size.width, backrgoundImage.size.height)]; 
[foregroundImage drawInRect:CGRectMake(backrgoundImage.size.width/2, backrgoundImage.size.height/2, foregroundImage.size.width, foregroundImage.size.height)]; 
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)]; 
[imageView setImage:newImage]; 

// Crop the final image to a circle 
CALayer *imageLayer = imageView.layer; 
[imageLayer setCornerRadius:imageView.frame.size.width/2]; 
[imageLayer setBorderWidth:1]; 
[imageLayer setMasksToBounds:YES]; 
imageLayer.borderColor = (__bridge CGColorRef _Nullable)([UIColor clearColor]); 

[self.view addSubview:imageView]; 
+0

Thanx habe ich Ähnliches implementiert, aber da uiimage keine contentMode -Eigenschaft hat, werden die Bilder gestreckt. – Ilya

+1

Sorry für den schlampigen Code. Ich war nicht vor meinem Computer. Bitte schauen Sie sich meinen bearbeiteten Code an. Das funktioniert bei mir ohne Verzerrung. Sie brauchen contentMode nicht, wenn Sie Bilder bearbeiten. Stellen Sie sicher, dass Sie die Koordinaten und die Größe richtig zuordnen, wenn Sie die Bilder überlappen. – Alex

+0

Können Sie meine aktualisierte Frage sehen? Ich habe mein Beispiel auch mit gestreckten Bildern gepostet. vielleicht wäre meine Sorge klar. Danke. – Ilya

Verwandte Themen