Swift 3 how to make background image fill the entire UIView? - swift3

I've created one UIView and change the background image to it by using the following code
slot1_view?.backgroundColor = UIColor(patternImage: UIImage(named: "drum_cut.png")!)
It's working fine on iphone but on ipad the background image become repeated.
How can I change its contentmode to something the fill the entire UIView?
Please help!!!!

Try this code-
Repeat:
var img = UIImage(named: "bg.png")
view.backgroundColor = UIColor(patternImage: img!)
Stretched
var img = UIImage(named: "bg.png")
view.layer.contents = img?.cgImage
Hope it helps!

Try this
let backgroundImage = UIImageView(frame: UIScreen.main.bounds)
backgroundImage.image = UIImage(named: "RubberMat")
backgroundImage.contentMode = UIViewContentMode.scaleAspectFill
self.view.insertSubview(backgroundImage, at: 0)

If you're using Swift5, try this on a button click event. you might need to do some layout margin for the UIView
myView?.contentMode = UIView.ContentMode.scaleToFill
myView.layer.contents = UIImage(named:"bg.png")?.cgImage
self.view.bringSubviewToFront(myView)

Swift 5
This work fine for view background image
let backgroundImage = UIImageView(frame: UIScreen.main.bounds)
backgroundImage.image = AppImageAssets.appAssets.appBackgroundImage()
backgroundImage.contentMode = UIView.ContentMode.scaleAspectFill
self.view.insertSubview(backgroundImage, at: 0)

Related

iOS15 Xcode 13 Global Accent Color not working

I'm using the latest beta of Xcode 13 with an app for iOS 14 and now I'm facing this strange issue:
The global accent color of my app was working fine until the iOS 15 update when the color is now set as the default blue where before it was my custom color.
Here is the asset catalog:
This is my project settings page where you can see that the accent color is correct.
And this is what the app looks like when built. The color is the default blue when it needs to be a really dark blue/purple color.
We were using the UIAppearance API in our app. We were not setting the tint color, but somehow calling any of the UIAppearance API's after the app has finished launching causes this behavior.
enum AppAppearance {
static func configure() {
configureCustomBarApperance()
UITableView.appearance().backgroundColor = UIColor(named: .primaryBackground)
UITextView.appearance().backgroundColor = nil
UIScrollView.appearance().keyboardDismissMode = .interactive
}
static func configureCustomBarApperance() {
let barAppearance = UIBarAppearance()
barAppearance.configureWithTransparentBackground()
barAppearance.backgroundColor = UIColor(named: .primaryBackground)
// Toolbars
let toolbarAppearance = UIToolbarAppearance(barAppearance: barAppearance)
UIToolbar.appearance().standardAppearance = toolbarAppearance
UIToolbar.appearance().compactAppearance = toolbarAppearance
UIToolbar.appearance().scrollEdgeAppearance = toolbarAppearance
// Navigation Bars
let navBarAppearance = UINavigationBarAppearance(barAppearance: barAppearance)
navBarAppearance.titleTextAttributes[.foregroundColor] = UIColor.secondaryLabel
UINavigationBar.appearance().standardAppearance = navBarAppearance
UINavigationBar.appearance().compactAppearance = navBarAppearance
UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
// Tab Bars
let tabBarAppearance = UITabBarAppearance()
tabBarAppearance.configureWithTransparentBackground()
tabBarAppearance.backgroundColor = UIColor(named: .secondaryBackground)
UITabBar.appearance().standardAppearance = tabBarAppearance
UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance
}
}
Our solution was to move all of the UIAppearance API work to the initializer of the AppDelegate and this fixed the issue for us. So instead of calling AppAppearance.configure() after the app finished launching...we call it from AppDelegate.init and our Global Accent Color is now being honored.
Don't ask me why...I couldn't tell you.
I finally found a temporary workaround on this AppleDeveloperForum Thread
credit to: #chad_sykes for this answer
I found an alternate solution, which was to set the .accentColor on the main view in the WindowGroup and it gets used across the app.
#main
struct CurvApp: App {
var body: some Scene {
WindowGroup {
myMainView
.accentColor(CurvGlobalAppearance.curvAccentColor)
}
}
}

Using Filters - CIMaskedVariableBlur

I have been gradually getting my head around filters but I can't for the life of me get this to work and there are minimal articles about this specific filter.
I have a mask (png) with a gradient between white and black and an image and I can't get it to blur an image called bg.png. The app crashes out with:
'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key inputMaskImage.'
let mask = CIImage(image: UIImage(named: "mask.png")!)
let context = CIContext()
let filter = CIFilter(name: "CIMaskedVariableBlur")
filter?.setValue(mask, forKey: kCIInputMaskImageKey)
let image = CIImage(image: UIImage(named: "bg.png")!)
filter?.setValue(image, forKey: kCIInputImageKey)
let result = filter?.outputImage!
let cgImage = context.createCGImage(result!, from:(result?.extent)!)
let outputImg = UIImage(cgImage: cgImage!)
bgImage.image = outputImg
I have been playing around with different ways of doing it but all give the same error and I assume it is to do with the mask type?... I have no idea!
If you are targeting iOS 8, the key kCIInputMaskImageKey won't work. It's only for iOS 9 or later. But the good news is you can get things to work in iOS 8 by typing in the name of the keys. I usually do this anyways. Here's a function that should work for you:
func applyMaskedVariableBlur(image:UIImage, mask:UIImage) -> UIImage {
let filter = CIFilter(name: "CIMaskedVariableBlur")
// convert UIImages to CIImages and set as input
let ciInput = CIImage(image: image)
let ciMask = CIImage(image: mask)
filter?.setValue(ciInput, forKey: "inputImage")
filter?.setValue(ciMask, forKey: "inputMask")
// get output CIImage, render as CGImage first to retain proper UIImage scale
let ciOutput = filter?.outputImage
let ciContext = CIContext()
let cgImage = ciContext.createCGImage(ciOutput!, from: (ciOutput?.extent)!)
return UIImage(cgImage: cgImage!)
}

AVPlayerLayer does not fill the UIVIew fully. What am I missing?

The video I'm playing does not take the entire area of the UIView (named videoView), which has a gray color: iPhone 7 Plus Simulator Screenshot
Most of the answers claim that I need to either set the frame to bounds (of UIView) or set videoGravity to AVLayerVideoGravityResizeAspectFill. I've tried both, but for some reason it still does not fill the space entirely.
var avPlayer: AVPlayer!
var avPlayerLayer: AVPlayerLayer!
var paused: Bool = false
#IBOutlet weak var videoView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let theURL = Bundle.main.url(forResource:"HOTDOG", withExtension: "mp4")
avPlayer = AVPlayer(url: theURL!)
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
avPlayerLayer.frame = videoView.layer.bounds
videoView.layer.insertSublayer(avPlayerLayer, at: 0)
}
Any help will be appreciated. :)
After long time I found the answer.
Code below should be moved into viewDidAppear() like:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Resizing the frame
avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
avPlayerLayer.frame = videoView.layer.bounds
videoView.layer.insertSublayer(avPlayerLayer, at: 0)
avPlayer.play()
paused = false
}
The layout was designed for iPhone SE (small screen), so when it was tested on a bigger screen the app was taking originally set size from the Auto-layout and shaping it according to that. By moving the code into viewDidAppear() the app resizes the window according to new constraints.
Just move the frame line avPlayerLayer.frame = videoView.layer.bounds into viewDidLayoutSubviews like this:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
avPlayerLayer.frame = videoView.layer.bounds
}
The rest should stick into the viewDidLoad function, just like you did.

iOS: How to take Screen shot of AVplayer?

To play videos in my project.I have created Custom video player(i.e AVplayerLayer instead of AVPlayerViewController) for custom controls.The problem is when i try to take a screenshot of videoPlayer it returns black image.
This is the code i have used to take a screenshot
func captureScreen() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
view.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
Any suggestions would be greatly helpful!
If you need to take a snapshot of a view containing an AVPlayerLayer, to use in animations/freeze states, you can also use view.snapshotView(afterScreenUpdates:).
This returns a view with a screenshot of your view.
Handy in combination with UIVisualEffectView! :)
Try this,hope it will help you...
extension UIView
{
public func getSnapshotImage() -> UIImage
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0)
self.drawHierarchy(in: self.bounds, afterScreenUpdates: false)
let snapshotImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return snapshotImage
}
}
Usage:
let Snap = self.VideoPlayerView.getSnapshotImage
Since you are using AVPlayer rather than AVAssetReader+AVAssetReaderTrackOutput(which can take screen shot just along with playing)
I guess this will help you.
if let item = player.currentItem {
let imageGenerator = AVAssetImageGenerator(asset: item.asset)
imageGenerator.appliesPreferredTrackTransform = true
if let cgImage = try? imageGenerator.copyCGImage(at: item.currentTime(), actualTime: nil) {
let image = UIImage(cgImage: cgImage)
}
}
TIP: You can get that item at you own way. (e. the same when you create the AVPlayer)
The assumptions just for safty which compiler indicates you. (You can forced unwrapping of course)

Swift 3 Change color of selected text in UITextView

I have just changed my code to Swift 3 from swift 2.3. The following code is working fine with swift 2.3 but there is no effect with swift 3.
I want to develop a customise text editor. And let user to select text and change its color. For that i am using this code.
let selectedRange = textView.selectedRange
let currentAttr = textView.textStorage.attributes(at: selectedRange.location, effectiveRange: nil)
var attrName = NSForegroundColorAttributeName
if !isForeGround{
attrName = NSBackgroundColorAttributeName
}
if currentAttr[attrName] == nil || currentAttr[attrName] as! UIColor != selectedUIColor{
let dict = [attrName:selectedUIColor]
let currentFont = currentAttr[NSFontAttributeName]
let fontDescriptor = (currentFont! as AnyObject).fontDescriptor
let updatedFont = UIFont(descriptor: fontDescriptor!, size: 0.0)
let dict2 = [NSFontAttributeName: updatedFont]
textView.textStorage.beginEditing()
if currentAttr.count>0{
textView.textStorage.addAttributes(dict, range: selectedRange)
}else{
textView.textStorage.setAttributes(dict, range: selectedRange)
}
textView.textStorage.addAttributes(dict2, range: selectedRange)
textView.textStorage.endEditing()
}
Runs successfully but there is no effect on text color.
This worked for me.
First you need to catch your selected text, with:
let selectedText = textView.selectedRange
Then, you create the attribute:
let myAttribute = [ NSForegroundColorAttributeName: selectedUIColor]
And lastly:
textView.textStorage.addAttributes(myAttribute, range: selectedText)
This must be in an Action called by any sender
Hope it works also for you!
Regards
Selected text can be changed with
self.textView.tintColor = .red