I'm getting a second long delay when selecting my collectionview cell. Here is my current code for collection view did select:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let vc = PopUpCellViewController(nibName: "PopUpCellViewController", bundle: nil)
self.navigationController?.pushViewController(vc, animated: true)
print("called")
let cell = collectionView.cellForItem(at: indexPath) as! AnnotatedPhotoCell
sourceCell = cell
vc.picture = resizeImage(image: cell.imageView.image!, targetSize: CGSize(width: (view.bounds.width - 45),height: 0))
vc.comment = cell.commentLabel
var image = UIImage(named: "back_button_thick")
image = image?.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
self.navigationController?.navigationBar.backIndicatorImage = image
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = image
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: UIBarButtonItemStyle.plain, target: nil, action: nil)
}
func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
let size = image.size
let widthRatio = targetSize.width / image.size.width
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
I am using a UIViewControllerAnimatedTransitioning. I am confident that there is no delay with my UIViewControllerAnimatedTransitioning. There seems to be an issue with my CollectionView Did select function. If switch my code in my didSelect function for a print statement, there is no longera delay.
I have two solutions:
1: PROBABLY NOT: I'm guessing that it's giving an annoying delay because it's taking a while for your app to run the code to get the nib file, and change all those things while it shouldn't.
2: PROBABLY: Perhaps running it on a real device will help. Xcode always has bugs, so don't worry. :)
Related
Here is some trouble I am having working with a UITableView, more precisely using an image in tableView:editActionsForRowAt:
Below follows my relevant code. It may be useful to say that the images I am using here are all square 70x70.
func tableView(_ tableView: UITableView,
editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
var patternImg:UIImage?
let upBtn = UITableViewRowAction(style: .normal, title: "") {
action, index in
print("upBtn button tapped")
}
patternImg = self.swipeCellImage(named: "UpIcn", side: 46.0)
upBtn.backgroundColor = UIColor(patternImage: patternImg!)
let downBtn = UITableViewRowAction(style: .normal, title: "") {
action, index in
print("downBtn button tapped")
}
patternImg = swipeCellImage(named: "DownIcn", side: 46.0)
downBtn.backgroundColor = UIColor(patternImage: patternImg!)
let rmvBtn = UITableViewRowAction(style: .destructive, title: "") {
action, index in
print("rmvBtn button tapped")
}
patternImg = swipeCellImage(named: "TrashIcn", side: 46.0)
rmvBtn.backgroundColor = UIColor(patternImage: patternImg!)
return [downBtn,upBtn,rmvBtn]
}
func swipeCellImage(named name: String, side: CGFloat) -> UIImage? {
let theImage = UIImage(named: name)
UIGraphicsBeginImageContextWithOptions(CGSize(width: side*2, height: side), false, UIScreen.main.scale)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(UIColor.clear.cgColor)
theImage?.draw(in: CGRect(x: 0, y: 0, width: side, height: side))
let resultImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return resultImage
}
Things work, but unfortunately only up to a certain point.
Looking at this screen shot shows that there is an unwanted repetion of the images. Clearly I want each button(Icon) to only appear one time each.
Can anyone see how I need to fix my code to avoid this repetion?
To avoid that, you have to increase width size asper your requirement.
UIGraphicsBeginImageContextWithOptions(CGSize(width: self.view.frame.width, height: commonHei), false, UIScreen.main.scale)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(textColor.cgColor) // CHECK BY CHANGE BGCOLOR
context!.fill(CGRect(x: 0, y: 0, width: (self.view.frame.width) / 3, height: commonHei)) // INCREASE WIDTH SIZE
var img: UIImage = UIImage(named: "pause")!
img.draw(in: CGRect(x: 0, y: 0, width: 30, height: 30)) // Change position as per ur requirement.
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
If you having more doubt, then check on the 3D view.
I'm using Swift 3.0 with Xcode 8 and I'm having some problems with image resizing. Here is the code where i set my UIImage frame.
open func setData(_ data: Any?, image: String) {
self.textLabel?.font = UIFont.boldSystemFont(ofSize: 10)
self.textLabel?.textColor = UIColor(hex: "000000")
if let menuText = data as? String {
self.textLabel?.text = menuText
}
self.imageView?.contentMode = UIViewContentMode.scaleToFill
self.imageView?.frame = CGRect(x: 12, y: 8, width: 10, height: 10)
self.imageView?.image = UIImage(named: image)
self.imageView?.clipsToBounds = true
}
And here is where I call my function inside my tableView. I don't have any problem with setting the image, but ONLY with resize. When i use smaller images, the image is smaller, when i use bigger images, the image gets bigger, it doesnt resize.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = BaseTableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: BaseTableViewCell.identifier)
cell.setData(menus[indexPath.row], image: images[indexPath.row])
return cell
}
I have solved it by using this resize function to resize my image and then place in the ImageView
func imageResize(image:UIImage,imageSize:CGSize)->UIImage
{
UIGraphicsBeginImageContextWithOptions(imageSize, false, 0.0)
[image .draw(in: CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))]
let newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext()
return newImage!
}
If you are using default image view of uitableview cell than you won't be able to resize it. Some default constraints are already there.
You have two options :
create a subclass of uitableview cell and use your own image view (don't create the outlet with name imageView, try something else).
Resize the image using https://stackoverflow.com/a/45100626/5383852
I need to have a screenshot of a specific UITableView row and remove/add content to the cell before the screenshot.
For example: the cell contains only a text and a share button. On share button click, I want the app to generate an image with the text and my app logo on the top (without the share button).
What is the best approach to do this? and how?
Thanks in advance.
#Nirav already gave you a hint in the comment section with this post:
How to take screenshot of portion of UIView?
So, you have now to get the Rect of the cell in the superview, so i made a sample action method:
#IBOutlet var snapImageView: UIImageView!
#IBAction func snapshotrow(_ sender: Any) {
//get the cell
if let cell = myTable.cellForRow(at: IndexPath(row: 0, section: 0)) as? MyCustomCellClass {
//hide button
cell.shareButton.isHidden = true
let rectOfCellInTableView = myTable.rectForRow(at: IndexPath(row: 0, section: 0))
let rectOfCellInSuperview = myTable.convert(rectOfCellInTableView, to: myTable.superview)
snapImageView.image = self.view.snapshot(of: rectOfCellInSuperview)
let finalImage = saveImage(rowImage: snapImageView.image)
//test final image
snapViewImage.image = finalImage
}
}
func saveImage(rowImage: UIImage) -> UIImage {
let bottomImage = rowImage
let topImage = UIImage(named: "myLogo")!
let newSize = CGSize.init(width: 41, height: 41) // set this to what you need
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
bottomImage.draw(in: CGRect(origin: .zero, size: newSize))
topImage.draw(in: CGRect(origin: .zero, size: newSize))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
and I was able to get the snapshot of the 0th cell of my table view and assigned it to the snapImageView.
Now the last step is to save the image to the camera roll, there are lots of related post out there in SO.
Source: Get Cell position in UITableview
Adding logo and hiding share button: Saving an image on top of another image in Swift
I have a tableView with a cell created in cellForRowAtIndexPath and add some dummy text:
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle,
reuseIdentifier: "cell")
cell.textLabel?.text = "Test Title"
cell.detailTextLabel?.text = "Test detail label"
Then I add a test image to the cell's imageView:
var image = UIImage(named: "cd.png")
cell.imageView!.image = image
Result:
To adjust the color, I use the following code:
cell.imageView?.tintColor = UIColor.redColor()
Result:
The image is too big in the cell, so I adjust the size using the following code:
var itemSize:CGSize = CGSizeMake(20, 20)
UIGraphicsBeginImageContextWithOptions(itemSize, false, UIScreen.mainScreen().scale)
var imageRect : CGRect = CGRectMake(0, 0, itemSize.width, itemSize.height)
cell.imageView!.image?.drawInRect(imageRect)
cell.imageView!.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
Whilst the image does resize, the tintColor is lost:
Any ideas please?
Solution Without custom cell
func imageWithImage(image: UIImage, scaledToSize newSize: CGSize) -> UIImage {
UIGraphicsBeginImageContext(newSize)
image.draw(in: CGRect(x: 0 ,y: 0 ,width: newSize.width ,height: newSize.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!.withRenderingMode(.alwaysOriginal)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
cell.imageView?.tintColor = UIColor.green
cell.imageView?.image = imageWithImage(UIImage(named: "imageName")!, scaledToSize: CGSize(width: 20, height: 20))
// Configure the cell...
return cell
}
You can do it by another way :
1) Create custom cell with your own UIImageView size and 2 separate labels
2) Add UIImageView as Subview of Cell
var cellImg : UIImageView = UIImageView(frame: CGRectMake(5, 5, 50, 50))
cellImg.image = UIImage(named: "yourimage.png")
cell.addSubview(cellImg)
in swift 4 :
func image( _ image:UIImage, withSize newSize:CGSize) -> UIImage {
UIGraphicsBeginImageContext(newSize)
image.draw(in: CGRect(x: 0,y: 0,width: newSize.width,height: newSize.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!.withRenderingMode(.automatic)
}
cell.imageView?.image = image(UIImage(named: "yourImage.png")!, withSize: CGSize(width: 30, height: 30))
For Swift 3
func imageWithImage(image:UIImage,scaledToSize newSize:CGSize)->UIImage{
UIGraphicsBeginImageContext( newSize )
image.draw(in: CGRect(x: 0,y: 0,width: newSize.width,height: newSize.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!.withRenderingMode(.alwaysTemplate)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
cell.imageView?.tintColor = UIColor.greenColor()
cell.imageView?.image = imageWithImage(image: UIImage(named: "imageName")!,scaledToSize: CGSize(width: 20, height: 20))
// Configure the cell...
return cell
}
For OBJECTIVE C without Custom tableViewCell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"abc" forIndexPath:indexPath];
// Configure the cell...
if (cell==nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"abc"];
}
cell.textLabel.text = [menuItemsArray objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:[menuItemsImagesArray objectAtIndex:indexPath.row]];
CGSize itemSize = CGSizeMake(20, 20);
UIGraphicsBeginImageContextWithOptions(itemSize, false, self.view.contentScaleFactor);
CGRect imageRect = CGRectMake(0, 0, itemSize.width, itemSize.height);
[cell.imageView.image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return cell; }
I came here because I was trying to find the answer to same question.
There are several answers that manipulate the image. I was having the same issue. but didn't want to manipulate the image.
What I did find that my images were 200x200 and dropped them as 1x.
I moved them to the 3x section and iOS would automatically resize them more to icon size. For everyone's reference I have added 1x vs 3x comparison
I thought to post as it did solve my issue. It might be helpful to anyone with the same intention as mine.
happy coding.
SwiftUI solution
Image("YourImage")
.resizable()
.scaledToFit()
.frame(width: 40, height: 40)
In case anyone is working with Xamarin, here is the snippet
private static UIImage ImageWithImage(UIImage image, CGSize newSize)
{
UIGraphics.BeginImageContext(newSize);
image.Draw(new CGRect(x: 0, y: 0, width: newSize.Width, height: newSize.Height));
var newImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return newImage.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
}
I'm a beginner with swift and I can't get the resize of a UIImageView working.
Here is my current layout :
What I want is to resize the images to occupy half the screen's width (2 images per row).
Here is my storyboard :
Here is the function drawing the collection view inside my controller :
func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell! {
var cell : MenuInspirationCellView = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as MenuInspirationCellView
cell.imageView.layer.borderWidth = 2
cell.imageView.layer.borderColor = UIColor.yellowColor().CGColor
//This is my first approach trying to modify the frame :
cell.imageView.frame = CGRectMake(0,0, self.view.bounds.width / 2,v120)
var cellImage : UIImage = UIImage(data: NSData(contentsOfURL: NSURL(string: images[indexPath.row])))
cell.imageView.image = cellImage;
//This is my second approach (based on http://www.snip2code.com/Snippet/89236/Resize-Image-in-iOS-Swift) :
// to resize an image to dimension 52x52
//var newSize:CGSize = CGSize(width: 52,height: 52)
//let rect = CGRectMake(0,0, newSize.width, newSize.height)
//UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
// image is a variable of type UIImage
//cellImage.drawInRect(rect)
//let newImage = UIGraphicsGetImageFromCurrentImageContext()
//UIGraphicsEndImageContext()
// resized image is stored in constant newImage
//cell.imageView.image = newImage;
//This is my thrid approach (based on https://gist.github.com/hcatlin/180e81cd961573e3c54d, of course i added his functions but I don't show them here for the sake of readability) :
//cell.imageView.image = self.RBSquareImageTo(cellImage, size: CGSize(width: 80, height: 80))
return cell
}
Any leads to sort this out ?
SWIFT:
func imageResize(imageObj:UIImage, sizeChange:CGSize)-> UIImage {
let hasAlpha = false
let scale: CGFloat = 0.0 // Automatically use scale factor of main screen
UIGraphicsBeginImageContextWithOptions(sizeChange, !hasAlpha, scale)
imageObj.drawInRect(CGRect(origin: CGPointZero, size: sizeChange))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext() // !!!
return scaledImage
}
The sizes of your cells are decided by your UICollectionViewLayout object, which is a UICollectionViewFlowLayout in your case. If you want all of your cells to be the same size, you can configure the properties on the layout itself; itemSize and minimumInterimSpacing will do the trick. Alternatively, if you want your cells to be different sizes, say depending on the image each contains or whatever, you needs your collection view delegate to implement the UICollectionViewDelegateFlowLayout method:
optional func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize
returning the size you want for each cell.
Following this tutorials you can resize UIImage, In that tutorial described fully .. Image Resize in swift ios8
func imageResize (imageObj:UIImage, sizeChange:CGSize)-> UIImage{
let hasAlpha = false
let scale: CGFloat = 0.0 // Automatically use scale factor of main screen
UIGraphicsBeginImageContextWithOptions(sizeChange, !hasAlpha, scale)
imageObj.drawInRect(CGRect(origin: CGPointZero, size: sizeChange))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
return scaledImage
}
Here you can also see many tutorials about Swift language Visit Here iPhone & iPad Application Development Help World