Top 5 iPhone App Development Latest Trends Need to know

Top 5 iPhone App Development Latest Trends Need to know

iOS most successful and fastest OS for iPhone, iPad and currently released iOS 13. We describe the top 5 iPhone app development trends which are very essential for the next iPhone project.

Check out some latest trends in iPhone app development.

iOS Tutorial: Steps to Integrate Multiple Windows Feature (Introduced in iOS 13) in iPadOS

iOS Tutorial: Steps to Integrate Multiple Windows Feature (Introduced in iOS 13) in iPadOS

Want to integrate multiple windows feature (introduced in iOS 13) in iPadOS? Visit this tutorial and know how to integrate multiple windows feature.

From this iOS tutorial, you will learn:

Different features integrated into iPadOS
What multiple windows on the iPad is
The types of windows
The benefits of using this feature
What types of apps can benefit from this feature
Steps to integrate multiple windows feature in iPadOS
iOS 13 was launched with a lot of new features and functionalities. These advancements were not only for iPhoneOS but also for iPadOS. In this blog, we will talk about one of the most important features that recently launched- multiple windows. Herein we will talk about how to integrate multiple windows feature in iPadOS.

With the release of iOS13, iPad has come nearer to functioning as the main computer. A lot of new features released in iOS13 have made iPad Pro a great MacBook replacement. Let us take a look at the new features that have accomplished this feat.

Desktop Class Safari
Multiple App Instances (Windows) At The Same Time
Safari Download Manager
External Devices Support in Files
Local Storage Management in Files
Better Text Manipulation
Automation with Shortcuts
Mouse Support
Better Home Screen
Dark Mode
The main feature that has led to this advancement is using multiple instances (or windows) for single or multiple apps at the same time.

What are the Multiple Windows on the iPad?
Previously, there was a feature that lets the users have multiple tabs of different apps on their iPad but multiple windows for the same or different applications were introduced in iOS 13.

This feature enables your app to run two instances of your interface side-by-side. In simple words, if it is a document-based app, people could have multiple document windows open at the same time. In simpler words, your users will love it.

Bonus: Multiple windows are created easily by using simple features of drag and drop.

What are the Types of Windows?
Primary window: It contains multiple app objects and the actions associated with them. People tend to interact with a primary window over time.
Auxiliary window: It contains a single object and the actions associated with it. People tend to interact with an auxiliary window only once before closing it.
What are the Benefits of Multiple Windows?
Multiple windows show different areas of the content. For instance, people might have one primary Mail window to display their Inbox and another to show their Drafts mailbox.
Auxiliary windows also give users additional views into the app’s content and functionality.
Users are enabled to act in one window and refer to something in the other window.
Which types of apps utilize this feature?
Most apps can utilize this feature in some way or another. Yet, it should be made sure that this feature is not mandatory for the functioning of your app. This feature is only to improve the multitasking feature of iPadOS and enhance user-experience.

Some examples of apps that utilize this feature in an appropriate manner.

Document-based apps
Navigation based apps (Maps)
Web browsing apps (Safari)
Dates/ Event management apps (Calendar)
Let us now see the steps of integrating multiple windows feature in iPadOS

Steps to Integrate Multiple Windows Feature in iPadOS

  1. Create a new project in Xcode

integrate multiple windows
2. Create a Single View Application

integrate multiple windows
3. Enter the project name (For instance, SOChatDemo)

integrate multiple windows
4. Create a “MainSplitViewController” class of UISplitViewController

SS4
5. Add and SplitViewController in Main.storyboard and assign MainSplitViewController class to it.

integrate multiple windows
integrate multiple windows
6. Drag and drop “Common”, “Model”, and “View” folder in the app (from demo app) because it is required for chat data (here, we are showing offline chat data)

integrate multiple windows
7. Add ChatListViewController class to show the Chat User list.

Get a UIViewController in main.storyboard and assign ChatListViewController class to it.

integrate multiple windows
8 Take IBOutlet of UITableview and declare an array of User’s Chat list from Model => MessageModel class (UserModel)

class ChatListViewController: UIViewController {

//MARK:- Variables
var arrUserList : [UsersModel] = []

//MARK:- IBOutlets
@IBOutlet weak var tblUsers: UITableView!

//MARK:- UIView Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
arrUserList = generateRandomUsers()
tblUsers.estimatedRowHeight = 76
tblUsers.rowHeight = UITableView.automaticDimension
tblUsers.reloadData()
tblUsers.dragDelegate = self
if arrUserList.count > 0 {
DispatchQueue.main.asyncAfter(deadline: .now()+0.2) {
self.tblUsers.selectRow(at: IndexPath(row: 0, section: 0), animated: false, scrollPosition: .top)
self.setDataInDetailVC(model: self.arrUserList[0])
}
}
}
}
9. In order to split the iPad screen for viewing two apps side by side, follow this code.

//MARK:- UITableViewDragDelegate Delegate

extension ChatListViewController: UITableViewDragDelegate {

func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {

let selectedMessage = arrUserList[indexPath.row]

let userActivity = selectedMessage.openDetailUserActivity

let itemProvider = NSItemProvider(object: UIImage(named: selectedMessage.displayImage)!)

itemProvider.registerObject(userActivity, visibility: .all)

let dragItem = UIDragItem(itemProvider: itemProvider)

dragItem.localObject = selectedMessage

return [dragItem]

}

}

//MARK:- UITableViewDelegate Delegate and UITableViewDataSource

extension ChatListViewController : UITableViewDelegate, UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

return arrUserList.count

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

if let cell : ChatUsersTableViewCell = tableView.dequeueReusableCell(withIdentifier: "ChatUsersTableViewCell") as? ChatUsersTableViewCell {

cell.cellConfig(user: arrUserList[indexPath.row])

return cell

}else {

return UITableViewCell()

}

}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

self.setDataInDetailVC(model: arrUserList[indexPath.row])

}

fileprivate func setDataInDetailVC(model:UsersModel) {

if let vc : MainSplitViewController = self.navigationController?.parent as? MainSplitViewController {

for childern in vc.children {

if let navVC = childern as? UINavigationController,let childVC = navVC.viewControllers.first as? ChatViewController {

childVC.userModel = model

childVC.refreshData()

}

}

}

}

}
10. Add ChatViewController class to show Chat Detail.

Get a UIViewController in main.storyboard and assign ChatViewController class to it.

To show the detail of chat we will fetch dummy messages from MessageModel and display in the list.

class ChatViewController: UIViewController {

//MARK:- Variables
var userModel : UsersModel!
var isValidFromOtherWindow : Bool = false
private var arrMessage : [Messages] = []
private var currentUser : UsersModel = UsersModel(senderID: String(0), displayName: generateRandomName(), profession: generateProfessionName(), displayImage: "22")
private var activeTextField : UITextView? = nil

//MARK:- IBOutlets
@IBOutlet weak var lblShadowMessage: UILabel!
@IBOutlet weak var txtMessage: UITextView!
@IBOutlet weak var tblMessages: UITableView!
@IBOutlet weak var btnSend: UIButton!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var containerView: UIView!

//MARK:- UIView Life Cycle
override func viewDidLoad() {
    super.viewDidLoad()
    setUI()
    if (isValidFromOtherWindow) {
        self.navigationItem.hidesBackButton = true
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(dismissViewController))
        
    }
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(self.insertMessages(_:)),
        name: .messageAddedNotifiation,
        object: nil)
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    if (isValidFromOtherWindow) {
        self.refreshData()
    }
    self.registerKeyboardNotifications()
    guard let user = userModel else {
        return
    }
    if #available(iOS 13.0, *) {
        view.window?.windowScene?.userActivity = user.openDetailUserActivity
    }
    
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.deRegisterKeyboardNotifications()
    if #available(iOS 13.0, *) {
        view.window?.windowScene?.userActivity = nil
    }
}

//MARK:- Set UI and Chat Configration
func refreshData() {
    arrMessage = generateRandomMessages(currentUser: currentUser, otherUser: userModel)
    guard self.tblMessages != nil else {
        return
    }
    self.tblMessages.reloadData()
    self.tblMessages.scrollToBottom()
}

fileprivate func setUI() {
    
    txtMessage.layer.cornerRadius = 4
    if (!isValidFromOtherWindow) {
        txtMessage.addDoneButtonOnKeyboard()
    }
    
    tblMessages.register(UINib(nibName: "IncommingChatMessageTableViewCell", bundle: nil), forCellReuseIdentifier: "IncommingChatMessageTableViewCell")
    tblMessages.register(UINib(nibName: "OutgoingChatMessageTableViewCell", bundle: nil), forCellReuseIdentifier: "OutgoingChatMessageTableViewCell")
    tblMessages.estimatedRowHeight = 70
    tblMessages.rowHeight = UITableView.automaticDimension
    tblMessages.reloadData()
    
}
  1. This method is responsible for creating window scenes and creating multiple windows.

@objc fileprivate func dismissViewController() {
if #available(iOS 13.0, *) {
var currentSession : UISceneSession? = nil
for session in UIApplication.shared.openSessions {
if let scene = session.scene,let currentScene = view.window?.windowScene,scene == currentScene {
currentSession = session
}
}
guard let session = currentSession else {
return
}
UIApplication.shared.requestSceneSessionDestruction(session, options: nil) { (error) in

        }
    }
    
}


fileprivate func setUpdateLayout() {
    self.view.updateConstraints()
    self.view.layoutIfNeeded()
    self.view.setNeedsLayout()
}

//MARK:- IBAction
@IBAction fileprivate func btnSendAction(_ sender: UIButton) {
    NotificationCenter.default.post(name: .messageAddedNotifiation, object: self.userModel, userInfo: ["data":[txtMessage.text ?? ""]])
    txtMessage.text = ""
    lblShadowMessage.text = ""
    txtMessage.resignFirstResponder()
}

}

//MARK:- UITableViewDelegate and UITableViewDataSource
extension ChatViewController : UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrMessage.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let message = arrMessage[indexPath.row]
    if message.sender.senderId == self.currentUser.senderId {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "OutgoingChatMessageTableViewCell") as? OutgoingChatMessageTableViewCell {
            cell.cellConfig(model: message)
            return cell
        }
    }else {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "IncommingChatMessageTableViewCell") as? IncommingChatMessageTableViewCell {
            cell.cellConfig(model: message)
            return cell
        }
    }
    
    return UITableViewCell()
}

}

//MARK:- UITextViewDelegate
extension ChatViewController : UITextViewDelegate {
func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
activeTextField = textView
return true
}
func textViewDidBeginEditing(_ textView: UITextView) {

}

func textViewDidEndEditing(_ textView: UITextView) {
    activeTextField = nil
}

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    let currentText = textView.text ?? ""
    guard let stringRange = Range(range, in: currentText) else { return false }
    let updatedText = currentText.replacingCharacters(in: stringRange, with: text)
    let previousHeight = lblShadowMessage.frame.height
    lblShadowMessage.text = updatedText
    self.tblMessages.layoutIfNeeded()
    self.setUpdateLayout()
    let newHeight = lblShadowMessage.frame.height - previousHeight
    tblMessages.contentOffset = CGPoint(x: 0, y: tblMessages.contentOffset.y + newHeight)
    self.tblMessages.layoutIfNeeded()
    return true
}

}

//MARK:- InputBarAccessoryViewDelegate
extension ChatViewController {

@objc fileprivate func insertMessages(_ notification:NSNotification) {
    guard let user = notification.object as? UsersModel else {
        return
    }
    guard let userModel = self.userModel else {
        return
    }
    if userModel.senderId != user.senderId {
        return
    }
    guard let dictData = notification.userInfo as? [String:Any],let data = dictData["data"] as? [String] else {
        return
    }
    if arrMessage.count == 0 {
        return
    }
    
    for component in data {
        if component.trimmingCharacters(in: .whitespacesAndNewlines).count == 0 {
            continue;
        }else{
            let message = Messages(sender: currentUser, messageId: String(Int(arrMessage[arrMessage.count-1].messageId) ?? 0 + 1), sentDate: Date(), message: component.trimmingCharacters(in: .whitespacesAndNewlines))
            arrMessage.append(message)
        }
        
    }
    self.tblMessages.reloadData()
    self.tblMessages.setNeedsDisplay()
    self.tblMessages.scrollToBottom()
}

}

//MARK: - Keyboard Notification observer Methods
extension ChatViewController {

fileprivate func registerKeyboardNotifications() {
        
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    

}

fileprivate func deRegisterKeyboardNotifications() {
           
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardDidHideNotification, object: nil)
}

@objc fileprivate func keyboardWillShow(notification: NSNotification) {
    
    if let activeTextField = activeTextField { // this method will get called even if a system generated alert with keyboard appears over the current VC.
        
        let info: NSDictionary = notification.userInfo! as NSDictionary
        let value: NSValue = info.value(forKey: UIResponder.keyboardFrameEndUserInfoKey) as! NSValue
        let keyboardSize: CGSize = value.cgRectValue.size
        
        let contentInsets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize.height, right: 0.0)
        scrollView.contentInset = contentInsets
        scrollView.scrollIndicatorInsets = contentInsets
        
        var aRect: CGRect = self.view.frame
        aRect.size.height -= keyboardSize.height
        let activeTextFieldRect: CGRect? = activeTextField.convert(activeTextField.frame, to: self.containerView)//activeTextField.frame
        
        let activeTextFieldOrigin: CGPoint? = activeTextFieldRect?.origin
        if (!aRect.contains(activeTextFieldOrigin!)) {
            scrollView.scrollRectToVisible(activeTextFieldRect!, animated:true)
        }
    }
}


@objc fileprivate func keyboardWillHide(notification: NSNotification) {
    
    let contentInsets: UIEdgeInsets = .zero
    scrollView.contentInset = contentInsets
    scrollView.scrollIndicatorInsets = contentInsets
}

}
Concluding Remarks
Apple might have introduced this feature quite late but you should not wait for anything now. If your app is the type that requires integrating multiple windows feature, then go for it. We hope that you found this iPhone tutorial useful in clearing your concept about this new feature.

In case, if you have any suggestions or queries in this tutorial or any questions related to iPhone app development, we are all ears. You may also feel free to tell us what we have missed in this or if you feel something is unclear.

We are a leading iPhone app development company and have hands-on experience in developing iOS apps with top features and functionalities. If you wish to develop a performance-oriented app with advanced features like this or want to hire iPhone developers, contact us. You may schedule a 30-min free consultation with our iOS developers and expert. All you need to do is fill the contact us form in the footer.

You may also like:

How to Integrate the New ‘Sign in with Apple’ Button in Your iOS App?

Top iOS Mobile App Development Agency in New York

Top iOS Mobile App Development Agency in New York

Are you looking for a [Top iOS Mobile App Development Agency in New York]**(https://www.appcluesinfotech.com/ios-app-develop**ment-company/ "Top iOS Mobile App Development Agency in New York") for your app projects? Then AppClues Infotech is the...

Are you looking for a Top iOS Mobile App Development Agency in New York for your app projects? Then AppClues Infotech is the reliable & trustworthy iOS mobile app development company in New York offering excellent iOS, iPhone, iPad and wearable app development, etc. technology solutions to their clients at an affordable price.

We believed to be one of the successful providers of iOS app development services. We have a dedicated team of developers and designers who have high knowledge and the best strength of developing any type of iOS apps.

Our iOS App Development Service:
• iOS App UX / UI Design
• Native & Hybrid iOS App Development
• App Redesigning
• iOS App Programming
• App Testing for flawless Performance
• App Support & Maintenance

For more info:
Visit: https://www.appcluesinfotech.com/
Email: [email protected]
Call: +1-978-309-9910

Top 10 Companies To Hire iPhone App Developer

Top 10 Companies To Hire iPhone App Developer

Searching to hire iPhone App Developer? This list will make you easy to hire iOS app developer for your next idea.

Are you searching ‘how to hire iPhone App Developers? This list of Top 10 Companies to hire iOS app developer will make you easy to find a reliable iPhone app development company. Below the list of the best iOS app development companies, is listed as per company review and ranking in the clutch and Good Firms. This Updated List of Top iPhone Application Development Companies will help you shortlist iOS app developers, hire ios developer that suits your project.

Read More:https://www.techgropse.com/blog/hire-iphone-app-developer/