David Koenig's Blog

News App - SwiftUI - Part II

04/23/2020

In Part Two we are creating all Views with SwiftUI to make the final User Interface!

In the Views/WebView.swift File, we define the View to help us translate a url to WebKit.

import Foundation import WebKit import SwiftUI struct WebView: UIViewRepresentable { let urlString: String? func makeUIView(context: Context) -> WKWebView { return WKWebView() } func updateUIView(_ uiView: WKWebView, context: Context) { if let safeString = urlString { if let url = URL(string: safeString) { let request = URLRequest(url: url) uiView.load(request) } } } }

The Views/ImageView.swift File, we create the View of an Image from that Image url.

import SwiftUI struct ImageViewURL: View { @ObservedObject var imageLoader:ImageLoader @State var image:UIImage = UIImage() init(withURL url:String) { imageLoader = ImageLoader(urlString:url) } var body: some View { VStack { Image(uiImage: imageLoader.data != nil ? UIImage(data:imageLoader.data!)! : UIImage()) .resizable() .aspectRatio(contentMode: .fit) .frame(width:100, height:100) } } } struct ImageView_Previews: PreviewProvider { static var previews: some View { ImageViewURL(withURL: "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Apple_logo_black.svg/500px-Apple_logo_black.svg.png") } }

Here we translate the image url to an actually displayed image.

In the Views/DetailView.swift uses the WebView with WebKit to display the article url in a browser.

import SwiftUI struct DetailView: View { let url: String? var body: some View { WebView(urlString: url) } } struct DetailView_Previews: PreviewProvider { static var previews: some View { DetailView(url: "https://www.davidkoenig.de") } }

The Final View is the Views/ContentView.swift where all comes together. Here will be our App completed.

import SwiftUI struct ContentView: View { @ObservedObject var networkManager = NetworkManager() init() { UITableView.appearance().separatorColor = .clear } var body: some View { NavigationView { List(networkManager.news) { news in ZStack { RoundedRectangle(cornerRadius: 25, style: .continuous) .fill(Color("card")) VStack(alignment: .leading , spacing: 20) { HStack { Text(news.title).foregroundColor(.red) } HStack(spacing: 20) { ImageViewURL(withURL: news.urlToImage ?? "https://cdn.pixabay.com/photo/2015/10/05/18/10/newspaper-973049_1280.jpg") Text(news.description).foregroundColor(.white) } HStack { NavigationLink(destination: DetailView(url: news.url)) { Text(news.url!).foregroundColor(.green) } } }.padding() } } .navigationBarTitle("German Top News") } .onAppear { self.networkManager.fetchData() } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView().preferredColorScheme(.dark) } }

Here you see the Navigation View with a List, which loops through and displaying a created card. Feel Free to play around with that code.


The complete project you can download at Github:

https://github.com/DKoenig82/swiftui_one/tree/main/news_app_swiftui-main
    
David Koenig